【问题标题】:CakePHP Basic Authentication and jQueryCakePHP 基本身份验证和 jQuery
【发布时间】:2014-06-01 10:15:06
【问题描述】:

我正在尝试使用完全用 jQuery 编写的应用程序在 CakePHP 中实现基本身份验证。我打算使用 OAuth2,但厌倦了增加的复杂性,并且认为这个应用程序将是唯一使用 API 的应用程序,基本身份验证应该就足够了。

登录方式如下:

login: function(username, password) {    
    $.ajax({
        type: 'GET',
        url: 'http://api.domain.com/login',
        beforeSend : function(xhr) {
            var base64 = $.base64.encode(username + ':' + password);
            xhr.setRequestHeader("Authorization", "Basic " + base64);
        },
        dataType: 'jsonp',
        success: function(data) {
            if( data.response.status == 'error' ) {
                alert(data.response.message);
            } else {                
                // Save some sort of session                   
            }
        },
        error: function(a,b,c) {
            console.log(a,b,c);
        }
    });        
}

在 CakePHP 方面:

public function login() {    
    if ($this->request->is('get')) {        
        if ($this->Auth->login()) {            
            $response = json_encode(
                array(
                    'meta'=>array(
                        'code'=>$this->response->statusCode(),
                        'in'=>round(microtime(true) - TIME_START, 4)
                    ),
                    'response'=>array(
                        'status'=>'success',
                        'message'=>'successfully logged in'
                    )
                )
            );                
        } else {   
            $response = json_encode(
                array(
                    'meta'=>array(
                        'code'=>$this->response->statusCode(),
                        'in'=>round(microtime(true) - TIME_START, 4)
                    ),
                    'response'=>array(
                        'status'=>'error',
                        'message'=>'incorrect login details'
                    )
                )
            );   
        }           
        // Handle JSONP
        if(isset($_GET['callback'])) {
            $response = $_GET['callback'] . '(' . $response . ')';
        }       
        // Return JSON
        $this->autoRender = false;
        $this->response->type('json');
        $this->response->body($response);           
    }       
}
  1. 如何保存用户登录详细信息?因为我无法创建会话,因为 JavaScript 可能不在同一台服务器上运行(因为它可能是外部应用程序、移动应用程序等)。数据将通过 SSL 发送,但我不确定如何我可以记住用户详细信息,因此用户不必继续登录。据我所知,基本身份验证应该是无状态的......所以甚至不存在 cookie 或会话。任何人都可以阐明这一点吗?

更新: 在对此进行了更多研究之后,我发现用户名和密码需要随每个请求一起发送......所以实际上从来没有会话或 cookie。但是我需要将这些信息存储在某个地方吗?否则用户会在页面上的每个请求后登录对吗?

  1. 一旦用户登录并通过身份验证...我如何向数据发出请求并处理身份验证以确保正确的用户具有访问权限,以及他们是否创建了作为他们创建的数据。与在 OAuth2 中一样,我将拥有一个 access_token,我可以将其传递给访问数据,但在 Basic Auth 中,您没有令牌。而且由于没有会话,我无法访问已登录的用户信息。那我该怎么做呢?

  2. 1234563用户名和密码?

更新:当尝试根据我上面的代码访问登录方法时,我收到了输入用户名和密码的提示...但这是一个允许方法!任何想法为什么?因为它阻止我的 JavaScript 发送请求,因为端点永远无法访问。此外,如果我使用提示登录,即使我访问注销方法或清除浏览器中的所有会话/缓存,我也 保持 登录。那么如何删除用户登录?

非常感谢任何能帮助我指明正确方向的人,因为我觉得我完全误解了 Basic Auth 的工作方式......一些例子会很棒!

更新 2:

根据 PHP Docs,以下是检查用户是否登录并在取消时显示消息的方法。信息也被存储,无需任何会话!那么同样的原则如何适用于 CakePHP 呢?例如,如何显示正确的 401 状态和自定义消息,如果基于此,登录的用户信息如何存储在 CakePHP 中?

<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="My Realm"');
    header('HTTP/1.0 401 Unauthorized');
    echo 'Text to send if user hits Cancel button';
    exit;
} else {
    echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
    echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
}
?>

【问题讨论】:

    标签: php jquery cakephp authentication


    【解决方案1】:

    虽然基本身份验证是无状态的,但根据 CakePHP 文档:

    使用基本身份验证的客户端必须支持 cookie。自从 AuthComponent 根据 Session 内容、客户端识别用户 使用 Basic Auth 必须支持 cookie。

    http://api.cakephp.org/2.5/class-BasicAuthenticate.html

    但是:

    您还可以将AuthComponent::$sessionKey 设置为 false 以确保 AuthComponent 不会尝试从会话中读取用户信息。无状态 身份验证将在每个请求上重新验证用户的凭据, 这会产生少量的额外开销,但允许客户端 无需使用 cookie 即可登录。

    http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#using-digest-and-basic-authentication-for-logging-in

    你的 AppController 应该是这样的:

    class AppController extends Controller {
    
        public $components = array('Auth', 'Session');
    
        public function beforeFilter() {
            $this->Auth->authorize = array('Controller');
            $this->Auth->authenticate = array('Basic');
            $this->Auth->sessionKey = false;
        }
    }
    

    您可能还想使用$this-&gt;Auth-&gt;unauthorizedRedirect = false;。默认情况下,未经授权的用户被重定向到引用 URL 或 AuthComponent::$loginAction 或 ‘/’。如果unauthorizedRedirect 设置为false,则会抛出 ForbiddenException 异常而不是重定向。

    然后在每个控制器中,您必须有isAuthorized() 方法,您可以根据用户的角色授权用户,就像使用通常的表单身份验证一样。例如:

    public function isAuthorized($user) {
       if (isset($user['role']) && ($user['role'] == 'admin')) {
         return true;
       }
       return false;
    }
    

    因为基本和摘要式身份验证不需要初始 POST 或一种形式,因此如果仅使用基本/摘要身份验证器,则无需 需要在您的控制器中进行登录操作。

    http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#using-digest-and-basic-authentication-for-logging-in

    这意味着您不需要显式调用 Users::login() 并且当用户尝试访问 URL 时,她将显示基本身份验证窗口,如果您不这样做,则每次请求页面时她都必须输入用户名和密码像在 Ajax 调用 xhr.setRequestHeader("Authorization", "Basic " + base64); 中一样发送基本授权标头。

    如果不希望用户在每次请求时都看到这样的窗口,您可以将用户凭据存储在 cookie 中,或者最好存储在客户端的本地存储 (http://www.w3schools.com/html/html5_webstorage.asp) 中,并在每个请求上设置“授权”标头(对任何控制器的任何操作)。

    您始终可以通过这种方式将经过身份验证的用户详细信息从控制器发送回客户端:

    $this->set(array(
         'user' => json_encode($this->Auth->user()),
         '_serialize' => array('user')
    ));
    

    也许您可以从beforeFilter() 执行此操作,以便在每个响应中发送经过身份验证的用户详细信息。

    【讨论】:

    • API 文档中“使用基本身份验证的客户端必须支持 cookie..”部分是谎言。 BasicAuthenticate 现在可以在无状态模式下正常工作。文档很快就会修复。
    【解决方案2】:

    可以在没有cookie的情况下使用会话,将其作为每个查询中的参数共享,并作为json响应的值。

    1. 准备您的应用程序以将 sessionID 存储在 database or cache

    2. ajax登录成功后,json响应中包含sessionID

    3. 每个下一个请求都必须包含 sessionID 作为参数,响应还必须包含 sessionID

    这就是我会做的。

    【讨论】:

    • 但是基本身份验证不使用会话对吗?它将身份验证详细信息存储在 AUTH_USER 和 AUTH_PW 变量中,并且没有到期时间。
    猜你喜欢
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 2011-01-28
    • 2013-11-10
    • 2013-01-13
    • 1970-01-01
    相关资源
    最近更新 更多