使用自定义身份验证适配器时检查 CakePHP 上的登录用户信息

Posted

技术标签:

【中文标题】使用自定义身份验证适配器时检查 CakePHP 上的登录用户信息【英文标题】:Checking logged-in user info on CakePHP when using a custom auth adapter 【发布时间】:2017-03-24 21:33:40 【问题描述】:

我正在使用 this JWTAuth adapter 在我的 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()trueController::beforeFilter()$this->Auth->user('id') 在控制器操作中可用,公共 仅限会员。 $this->Auth->loggedIn() 在控制器操作中是 true,公共 仅限会员。

使用 JWT 身份验证时:

$this->Auth->user('id')Controller::beforeFilter() 中是 null$this->Auth->loggedIn()falseController::beforeFilter()$this->Auth->user('id') 可用于仅限成员的控制器操作,null 可用于公共控制器操作。 $this->Auth->loggedIn() 在仅限成员的控制器操作中是 true,在公共控制器操作中是 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"
);

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

只想提一下,在 CakePHP 3.x 中,AuthComponent 可以配置为在其 initialize() 方法中运行身份验证过程,该方法在控制器的 beforeFilter() 之前运行。 怎么样`Cakephp 2` 我如何在beforeFilter 中获取用户信息?我认为这个解决方案只适用于Cakephp 3 @KenanaReda 请看我的回答——我找到了解决办法!【参考方案2】:

我有点晚了,但我找到了解决这个问题的方法,但是(警告!)它涉及更新 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();

瞧,您现在可以在使用无状态身份验证访问不受保护的控制器功能时访问服务器上的用户信息!

【讨论】:

已经有条件检查_getuser() 所以只需添加这一行没有区别,它仍然无法识别beforefilter 中的用户是否有任何其他配置? 您好 Kenana,我不知道您使用的是什么无状态身份验证系统。您可以使用这种方法(修补 AuthComponent)来查找您可能需要进行的修改! @caitlin 请避免更新源代码,因为升级蛋糕版本时您将丢失更改。请尝试我的解决方案。 @Farhan 当您像我一样进行更改时,升级库时更改不会被覆盖。我没有看到你的解决方案。你是在这里发的吗? @caitlin 您可以在 beforeFilter() 中将身份验证组件初始化为 $this->Auth->startup($this);

以上是关于使用自定义身份验证适配器时检查 CakePHP 上的登录用户信息的主要内容,如果未能解决你的问题,请参考以下文章

未找到CakePhp 3插件身份验证适配器

CakePHP 2.2.1 - 在表单上显示 CakePHP 错误 - 自定义验证

CakePHP 3自定义验证:如何在编辑期间将新值与旧值进行比较?

在电子邮件密码身份验证中进行额外的自定义检查 (Flutter - Firebase)

自定义摘要身份验证

如何使用 Windows 身份验证并注册自定义身份验证管理器