Yii2中的自定义身份验证问题

时间:2015-03-19 03:28:14

标签: php yii yii2

我为Yii2 RESTful项目添加了一个自定义身份验证组件,它正在验证凭据确定但它没有将有效的User对象返回到\ Yii :: $ app-> user

该组件如下所示:

public function authenticate($user, $request, $response) {

    $bearerToken = \Yii::$app->getRequest()->getQueryParam('bearer_token');

    $user = Account::findIdentityByAccessToken($bearerToken);

    return $user;
}

帐户模型方法如下所示:

public static function findIdentityByAccessToken($token, $userType = null) {

    return static::findOne(['bearer_token' => $token]);
}

我可以看到$ user是在authenticate()方法中调试时的预期记录,但\ Yii :: app() - >用户似乎是一个新实例化的用户。 \ Yii :: app() - > user-> identity等于null。

谁能看到我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

要登录用户,这还不够:

Account::findIdentityByAccessToken($bearerToken);

您需要在$user->login($identity)内拨打authentificate()。例如,请参阅yii\web\User loginByAccessToken()中的实施方式:

public function loginByAccessToken($token, $type = null)
{
    /* @var $class IdentityInterface */
    $class = $this->identityClass;
    $identity = $class::findIdentityByAccessToken($token, $type);
    if ($identity && $this->login($identity)) {
        return $identity;
    } else {
        return null;
    }
}

因此,您也可以使用自定义身份验证方法调用它:

$identity = $user->loginByAccessToken($accessToken, get_class($this));

例如,请参阅yii\filters\auth\QueryParamAuth中的实施方式。

您还需要返回$identity,而不是$user。您的代码中也缺少处理失败。了解它是如何在内置的auth方法中实现的:

更多来自官方文档:

<强>更新

没有任何东西强迫你使用loginByAccessToken(),我刚刚提到它作为一个例子。

以下是我很久以前写过的自定义身份验证方法的示例,不确定它是否100%安全且真实,但我希望它可以帮助您理解这些细节:

自定义身份验证方法:

<?php

namespace api\components;

use yii\filters\auth\AuthMethod;

class HttpPostAuth extends AuthMethod
{
    /**
     * @see yii\filters\auth\HttpBasicAuth
     */
    public $auth;

    /**
     * @inheritdoc
     */
    public function authenticate($user, $request, $response)
    {
        $username = $request->post('username');
        $password = $request->post('password');

        if ($username !== null && $password !== null) {
            $identity = call_user_func($this->auth, $username, $password);
            if ($identity !== null) {
                $user->switchIdentity($identity);
            } else {
                $this->handleFailure($response);
            }
            return $identity;
        }

        return null;
    }
}

REST控制器中的用法:

/**
 * @inheritdoc
 */
public function behaviors()
{
    $behaviors = parent::behaviors();

    $behaviors['authenticator'] = [
        'class' => HttpPostAuth::className(),
        'auth' => function ($username, $password) {
            $user = new User;
            $user->domain_name = $username;

            // This will validate password according with LDAP
            if (!$user->validatePassword($password)) {
                return null;
            }

            return User::find()->username($username)->one();
        },
    ];

    return $behaviors;
}

也可以在$auth中找到HttpBasicAuth callable。