Yii2-Api:如何为 HttpBearer 过滤器传递令牌
Yii2-Api: How to pass Token for the HttpBearer Filter
Here is my Controller
class ClientController extends ActiveController
{
public $modelClass = 'common\models\Client';
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items',
];
public function behaviors()
{
return ArrayHelper::meenter code hererge(parent::behaviors(),[
[
'class' => \yii\filters\Cors::className(),
],
[
'class' => CompositeAuth::className(),
'except' => ['options'],
'authMethods' => [
HttpBearerAuth::className(),
QueryParamAuth::className(),
],
],
[
'class' => TimestampBehavior::className(),
],
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['view', 'index'], // in a controller
// if in a module, use the following IDs for user actions
// 'only' => ['user/view', 'user/index']
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
],
[
'class' => AccessControl::className(),
// We will override the default rule config with the new AccessRule class
'ruleConfig' => [
'class' => AccessRule::className(),
],
'only' => ['create', 'delete'],
'rules' => [[
'actions' => ['create'],
'allow' => true,
// Allow users, moderators and admins to create
'roles' => [
User::ROLE_ADMIN
],
],
[
'actions' => ['delete'],
'allow' => true,
// Allow admins to delete
'roles' => [
User::ROLE_ADMIN
],
],
],
],
]);
}
public function actions(){
$actions = parent::actions();
unset( $actions['create']);
return $actions;
}
public function actionCreate(){
$model = new \common\models\Client();
$transaction = Yii::$app->db->beginTransaction();
try
{
$model->load(Yii::$app->getRequest()->getBodyParams(), '');
$user_create = \common\models\User::user_create($model);
if($user_create){
$model->user_id = $user_create->id;
if($model->save()){
$transaction->commit();
return $model;
}
}
}
catch (Exception $e)
{
$transaction->rollBack();
return null;
}
}
Here is my User Model
class User extends ActiveRecord implements IdentityInterface
{
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
public function generateAccountActivationToken()
{
$this->account_activation_token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* @inheritdoc
*/
// public static function findIdentityByAccessToken($token, $type = null)
// {
// throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
// }
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['auth_key' => $token]);
}
/**
* Finds user by username
*
* @param string $username
* @return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
}
/**
* Finds user by password reset token
*
* @param string $token password reset token
* @return static|null
*/
public static function findByPasswordResetToken($token)
{
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
$parts = explode('_', $token);
$timestamp = (int) end($parts);
if ($timestamp + $expire < time()) {
// token expired
return null;
}
/**
* @inheritdoc
*/
public function getId()
{
return $this->getPrimaryKey();
}
/**
* @inheritdoc
*/
public function getAuthKey()
{
return $this->auth_key;
// return null;
}
/**
* @inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomKey();
}
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if ($this->isNewRecord) {
$this->auth_key = \Yii::$app->security->generateRandomString();
}
return true;
}
return false;
}
}
The issue here is when i send post request it return 401 error.I know
it is athentication error it even didnt hit the function
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['auth_key' => $token]);
}
I kown the issue is here at HttpBearerAuth::className(). How i can fix this error here is the image
关于声明
It does not even land on the findIdentityByAccessToken()
来自DOCS
After authentication, for every API
request, the requested controller will try to authenticate the user in
its beforeAction()
step.
If authentication succeeds, the controller will perform other checks
(such as rate limiting, authorization) and then run the action. The
authenticated user identity information can be retrieved via
Yii::$app->user->identity
.
If authentication fails, a response with HTTP status 401 will be sent
back together with other appropriate headers (such as a
WWW-Authenticate header for HTTP Basic Auth).
HttpBearerAuth
extends HttpHeaderAuth
这是一个通过 HTTP Headers
支持 HTTP 身份验证的动作过滤器,查看 HttpHeaderAuth
函数的源代码 authenticate($user, $request, $response)
你会看到它在第一行
中获得了 auth headers
$authHeader = $request->getHeaders()->get($this->header);
和returns只有$identity
如果authHeaders
不是null
,否则returnsnull
来自authenticate($user, $request, $response)
方法,你甚至没有登陆 findIdentityByAccesToken()
就收到 401
错误。
你应该做的是
- 打开
postman
并单击 Authorization
选项卡
- Select
Type
从 drop-down BearerToken
- 在右侧添加来自用户 table 的
auth_key
作为您向 发送请求的用户
- 单击预览请求 按钮,您将看到消息请求headers 已更新
现在,如果您转到 Headers
选项卡,它紧邻 Authorization
标签你会看到key=>value
对授权headers
现在单击“发送”按钮并查看您的请求。我建议您注释掉当前操作中的所有内容,只需添加一个 echo "hello";
语句即可知道它已到达那里。
您可以通过以下方式通过curl发送headers进行身份验证
curl -d "param1=value1¶m2=value2"
-H "Content-Type: application/x-www-form-urlencoded"
-H "Authorization: Bearer YOUR_TOKEN_"
-X POST http://localhost:3000/data
Here is my Controller
class ClientController extends ActiveController
{
public $modelClass = 'common\models\Client';
public $serializer = [
'class' => 'yii\rest\Serializer',
'collectionEnvelope' => 'items',
];
public function behaviors()
{
return ArrayHelper::meenter code hererge(parent::behaviors(),[
[
'class' => \yii\filters\Cors::className(),
],
[
'class' => CompositeAuth::className(),
'except' => ['options'],
'authMethods' => [
HttpBearerAuth::className(),
QueryParamAuth::className(),
],
],
[
'class' => TimestampBehavior::className(),
],
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['view', 'index'], // in a controller
// if in a module, use the following IDs for user actions
// 'only' => ['user/view', 'user/index']
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
],
[
'class' => AccessControl::className(),
// We will override the default rule config with the new AccessRule class
'ruleConfig' => [
'class' => AccessRule::className(),
],
'only' => ['create', 'delete'],
'rules' => [[
'actions' => ['create'],
'allow' => true,
// Allow users, moderators and admins to create
'roles' => [
User::ROLE_ADMIN
],
],
[
'actions' => ['delete'],
'allow' => true,
// Allow admins to delete
'roles' => [
User::ROLE_ADMIN
],
],
],
],
]);
}
public function actions(){
$actions = parent::actions();
unset( $actions['create']);
return $actions;
}
public function actionCreate(){
$model = new \common\models\Client();
$transaction = Yii::$app->db->beginTransaction();
try
{
$model->load(Yii::$app->getRequest()->getBodyParams(), '');
$user_create = \common\models\User::user_create($model);
if($user_create){
$model->user_id = $user_create->id;
if($model->save()){
$transaction->commit();
return $model;
}
}
}
catch (Exception $e)
{
$transaction->rollBack();
return null;
}
}
Here is my User Model
class User extends ActiveRecord implements IdentityInterface
{
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
public function generateAccountActivationToken()
{
$this->account_activation_token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* @inheritdoc
*/
// public static function findIdentityByAccessToken($token, $type = null)
// {
// throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
// }
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['auth_key' => $token]);
}
/**
* Finds user by username
*
* @param string $username
* @return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
}
/**
* Finds user by password reset token
*
* @param string $token password reset token
* @return static|null
*/
public static function findByPasswordResetToken($token)
{
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
$parts = explode('_', $token);
$timestamp = (int) end($parts);
if ($timestamp + $expire < time()) {
// token expired
return null;
}
/**
* @inheritdoc
*/
public function getId()
{
return $this->getPrimaryKey();
}
/**
* @inheritdoc
*/
public function getAuthKey()
{
return $this->auth_key;
// return null;
}
/**
* @inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomKey();
}
public function beforeSave($insert)
{
if (parent::beforeSave($insert)) {
if ($this->isNewRecord) {
$this->auth_key = \Yii::$app->security->generateRandomString();
}
return true;
}
return false;
}
}
The issue here is when i send post request it return 401 error.I know it is athentication error it even didnt hit the function public static function findIdentityByAccessToken($token, $type = null) { return static::findOne(['auth_key' => $token]); } I kown the issue is here at HttpBearerAuth::className(). How i can fix this error here is the image
关于声明
It does not even land on the
findIdentityByAccessToken()
来自DOCS
After authentication, for every API request, the requested controller will try to authenticate the user in its
beforeAction()
step.If authentication succeeds, the controller will perform other checks (such as rate limiting, authorization) and then run the action. The authenticated user identity information can be retrieved via
Yii::$app->user->identity
.If authentication fails, a response with HTTP status 401 will be sent back together with other appropriate headers (such as a WWW-Authenticate header for HTTP Basic Auth).
HttpBearerAuth
extends HttpHeaderAuth
这是一个通过 HTTP Headers
支持 HTTP 身份验证的动作过滤器,查看 HttpHeaderAuth
函数的源代码 authenticate($user, $request, $response)
你会看到它在第一行
$authHeader = $request->getHeaders()->get($this->header);
和returns只有$identity
如果authHeaders
不是null
,否则returnsnull
来自authenticate($user, $request, $response)
方法,你甚至没有登陆 findIdentityByAccesToken()
就收到 401
错误。
你应该做的是
- 打开
postman
并单击Authorization
选项卡
- Select
Type
从 drop-downBearerToken
- 在右侧添加来自用户 table 的
auth_key
作为您向 发送请求的用户
- 单击预览请求 按钮,您将看到消息请求headers 已更新
现在,如果您转到 Headers
选项卡,它紧邻 Authorization
标签你会看到key=>value
对授权headers
现在单击“发送”按钮并查看您的请求。我建议您注释掉当前操作中的所有内容,只需添加一个 echo "hello";
语句即可知道它已到达那里。
您可以通过以下方式通过curl发送headers进行身份验证
curl -d "param1=value1¶m2=value2"
-H "Content-Type: application/x-www-form-urlencoded"
-H "Authorization: Bearer YOUR_TOKEN_"
-X POST http://localhost:3000/data