CakePHP基本身份验证和jQuery

CakePHP基本身份验证和jQuery,php,jquery,cakephp,authentication,Php,Jquery,Cakephp,Authentication,我试图用完全用jQuery编写的应用程序在CakePHP中实现基本身份验证。我本来打算使用OAuth2,但对增加的复杂性感到厌倦,因为这个应用程序将是唯一使用API的应用程序,基本的身份验证应该足够了 登录方法如下所示: login: function(username, password) { $.ajax({ type: 'GET', url: 'http://api.domain.com/login', beforeSend

我试图用完全用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);           
    }       
}
  • 如何保存用户登录详细信息?由于JavaScript可能不在同一台服务器上运行(可能是外部应用程序、移动应用程序等),因此我无法创建会话。数据将通过SSL发送,但我不确定如何记住用户详细信息,因此用户不必一直登录。据我所知,基本身份验证应该是无状态的。。。因此,甚至不存在cookie或会话。有人能解释一下吗
  • 更新: 在对此做了更多的研究之后,我发现每个请求都需要发送用户名和密码。。。因此,实际上从来没有会话或cookie。但是我需要把这些信息储存在什么地方?否则用户将在页面上的每个请求之后登录,对吗

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

  • 根据CakePHP文档,在CakePHP 2.4+中您不需要登录方法(用于基本身份验证),那么用户从客户端登录的具体方式是什么?在传递用户名和密码时,我会使用什么控制器方法

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

    如果能帮我指出正确的方向,我将不胜感激,因为我觉得我完全误解了Basic Auth的工作方式。。。一些例子会很棒

    更新2:

    根据PHP文档,以下是检查用户是否登录的方法,如果用户取消登录,则显示消息。信息也可以在不使用任何会话的情况下存储!那么同样的原理如何应用于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>";
    }
    ?>
    

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

  • 准备应用程序以在其中存储sessionID

  • 成功的ajax登录后,json响应中包含sessionID

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


  • 这就是我应该做的。

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

  • 准备应用程序以在其中存储sessionID

  • 成功的ajax登录后,json响应中包含sessionID

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


  • 这就是我要做的。

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

    使用基本身份验证的客户端必须支持cookie。自从 AuthComponent根据会话内容和客户端标识用户 使用基本身份验证必须支持cookies

    但是:

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

    您的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->Auth->unauthorizedRedirect=false。默认情况下,未经授权的用户被重定向到引用者URL或AuthComponent::$loginAction或
    “/”
    。如果
    unauthorizedDirect
    设置为
    false
    将引发禁止异常,而不是重定向

    然后,在每个控制器中,您必须具有
    isAuthorized()
    方法,在该方法中,您可以根据用户的角色对用户进行授权,就像对常规表单身份验证所做的那样。例如:

    public function isAuthorized($user) {
       if (isset($user['role']) && ($user['role'] == 'admin')) {
         return true;
       }
       return false;
    }
    
    因为基本和摘要身份验证不需要初始POST 或者,如果只使用基本/摘要验证器,则不使用 需要在控制器中执行登录操作

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

    如果您不希望在每个请求上向用户显示这样的窗口,则可以将用户凭据存储在cookie中,或者最好存储在客户端的本地存储()中,并在每个请求上设置“Authorization”(授权)头(任何控制器的任何操作)

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

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