当使用自定义认证适配器时,在CakePHP上检查登录的用户信息


Checking logged-in user info on CakePHP when using a custom auth adapter

我使用这个JWTAuth适配器在我的CakePHP 2.8应用程序中使用JWT身份验证而不是基于cookie的身份验证。它工作得很好,除了一个问题:

通常对于我的一个REST端点,我可以使用$this->Auth->user("id")来获取当前登录用户的ID。

当我尝试使用$this->Auth->allow()使非成员可以访问控制器动作时,出现了问题。如果我这样做,在控制器中使用$this->Auth->loggedIn()返回false,这意味着我不能为登录用户添加额外的逻辑。

当使用标准cookie验证时:

  • $this->Auth->user('id')Controller::beforeFilter()
  • $this->Auth->loggedIn()true inController::beforeFilter()
  • $this->Auth->user('id')在控制器动作中可用,public和会员制。
  • $this->Auth->loggedIn()是控制器动作中的true, public和会员制。

使用JWT授权时:

  • $this->Auth->user('id')Controller::beforeFilter()中的null
  • $this->Auth->loggedIn()false inController::beforeFilter()
  • $this->Auth->user('id')在member -only controller actions中可用,null在public controller actions中可用。
  • $this->Auth->loggedIn()在member -only controller actions中为true,在public controller actions中为false

是否有任何方法可以让Auth包含由JWTAuth组件返回的关于$this->Auth->allow()已公开的操作的信息?

控制器示例:

public function visible(){
    // This will always be false, even if a valid JWT token is sent
    $this->set("loggedIn", $this->Auth->loggedIn());
}
public function members_only(){
    // This will be unavailable if not logged in, and a true if logged in
    $this->set("loggedIn", $this->Auth->loggedIn());
}
public function beforeFilter($options = array()){
    parent::beforeFilter();
    $this->Auth->allow("visible");
}

作为参考,我的AppController::components数组;

public $components = array(
    'DebugKit.Toolbar',
    'Auth' => array(
        'authorize' => array(
            'Actions' => array(
                'actionPath' => 'controllers'
            ),
        ),
        'authenticate' => array(
            'Form' => array(
                'fields' => array('username' => 'email'),
                'contain' => array(
                    'UserProfile',
                )
            ),
            'JwtAuth.JwtToken' => array(
                'fields' => array(
                    'username' => 'email',
                    'token' => 'password',
                ),
                'header' => 'AuthToken',
                'userModel' => 'User',
            ),
        ),
        'unauthorizedRedirect' => false
    ),
    "Acl",
    "RequestHandler",
    "Session"
);

对于无状态适配器,在AuthComponent::startup()中触发身份验证过程。组件的startup()方法在 Controller::beforeFilter()之后运行,这就是为什么AuthComponent::user()不返回任何信息。

对于其他适配器,当用户进行身份验证时,身份信息存储在会话中。获取该信息不需要任何身份验证过程,这就是为什么AuthComponent::user()在标准的基于cookie的认证情况下给你用户信息。

我有点晚了,但我找到了一个解决这个问题的方法,但是(警告!)它涉及更新AuthComponent的代码。

我复制了Lib/Controller/Component/AuthComponent.php,并把它放在app/Controller/Component/AuthComponent.php下。

然后在文件中添加一行:

public function startup(Controller $controller) {
    $methods = array_flip(array_map('strtolower', $controller->methods));
    $action = strtolower($controller->request->params['action']);
    // One-line modification from the ordinary CakePHP file.
    // This lets us have info on the logged-in user in public actions when using stateless auth.
    $this->_getUser();

瞧,你现在可以访问服务器上的用户信息,同时访问无状态授权的非受保护的控制器功能!