自定义身份验证问题
问题描述:
我添加了一个自定义验证组件的Yii2 REST风格的项目,它是验证凭据OK,但它没有返回有效的用户对象为\的Yii :: $ APP->用户自定义身份验证问题
的组件是这样的:
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]);
}
我可以看到$用户帐户的预期记录在AU调试时thenticate()方法,但\ Yii :: app() - >用户似乎是一个新安装的用户。 \ Yii :: app() - > user-> identity等于null。
任何人都可以看到我在做什么错在这里?
答
要登录的用户,这是不够的:
Account::findIdentityByAccessToken($bearerToken);
你需要调用$user->login($identity)
内authentificate()
。例如,见它是如何在yii\web\UserloginByAccessToken()实施:
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
。您的代码中也缺少处理失败。看看它是如何在内置的身份验证方法来实现:
更多来自官方的文档:
更新:
没有强迫你使用loginByAccessToken()
,我刚才提到它作为一个例子。
这里是我写的很长一段时间前,不知道这是否是100%的安全和真正的定制身份验证方法的一个例子,但我希望它可以帮助你了解这些细节:
自定义身份验证方法:在REST控制器
<?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;
}
}
用法:
/**
* @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
找到。
谢谢。你为我清理了它。我没有重新确认我的auth方法应该调用内置的loginByAccessToken(),而后者会调用我自定义的findIdentityByAccessToken()方法。 我是否也可以通过用户名和密码进行查找,因为我想自定义这些?我看不到找到loginByAccessToken()等价物。 – Dubby 2015-03-19 05:33:09
对不起,上面应该是电子邮件和密码。 – Dubby 2015-03-19 05:49:43
没有什么会强制你使用这种方法。我只是提到这个例子。我用另一个例子更新了答案。 – arogachev 2015-03-19 06:22:03