在 yii2 中覆盖 Rest 身份验证(HttpBearerAuth)的响应
Override response of Rest authentication(HttpBearerAuth) in yii2
我有基于令牌的授权,为此我做了以下更改。
在 User 模型中,重写 findIdentityByAccessToken()
方法,如下所示。
public static function findIdentityByAccessToken($token, $type = null)
{
$userlogin = Userdevices::find()->where(['access_token' => $token])->one();
if ($userlogin == array()) {
return null;
} else {
$User = Users::findOne(['id' => $userlogin->user_id]);
if (!count($User))
{
return null;
}
else {
$dbUser = [
'id' => $User->id,
];
return new static($dbUser);
}
}
}
在 Controller 中,我添加 behaviors()
如下。
public function behaviors()
{
$behaviors[] = [
'class' => \yii\filters\ContentNegotiator::className(),
'formats' => [
'application/json' => \yii\web\Response::FORMAT_JSON,
],
];
$behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
];
return $behaviors;
}
当 API 未获得令牌或令牌无效时,它给出以下响应
{
"name": "Unauthorized",
"message": "You are requesting with an invalid credential.",
"code": 0,
"status": 401,
"type": "yii\web\UnauthorizedHttpException"
}
我想根据我的要求更改响应,如下所示。
{
"code": 401,
"name": "Unauthorized",
"is_logout": "Y",
"status": "error",
"message": "logout"
}
您可以使用 yii\web\Response
的 beforeSend
事件更改响应格式。
例如,在您的 api 控制器中添加以下方法:
public function init()
{
parent::init();
\Yii::$app->response->on(
\yii\web\Response::EVENT_BEFORE_SEND,
[$this, 'beforeResponseSend']
);
}
public function beforeResponseSend(\yii\base\Event $event)
{
/**
* @var \yii\web\Response $response
*/
$response = $event->sender;
if ($response->data['status'] == 401) {
$response->data = [
'code' => 401,
'name' => 'Unauthorized',
'is_logout' => 'Y',
'status' => 'error',
'message' => 'logout',
];
}
}
控制器的init
方法注册了beforeSend
事件。 beforeResponseSend
方法处理事件并更改响应格式。
如果你想在多个控制器中格式化响应,最好将事件处理程序放入自己的 class 例如
namespace app\components;
class ErrorResponseHelper
{
public static function beforeResponseSend(Event $event)
{
// ... formating code ...
}
}
并在config/web.php
中注册事件
return [
// ...
'components' => [
'response' => [
'class' => 'yii\web\Response',
'on beforeSend' => [
\app\components\ErrorResponseHelper::class,
'beforeResponseSend',
],
],
],
];
但是要小心这个解决方案,因为这样 \app\components\ErrorResponseHelper::beforeResponseSend
将在每个请求期间被调用。
我有基于令牌的授权,为此我做了以下更改。
在 User 模型中,重写 findIdentityByAccessToken()
方法,如下所示。
public static function findIdentityByAccessToken($token, $type = null)
{
$userlogin = Userdevices::find()->where(['access_token' => $token])->one();
if ($userlogin == array()) {
return null;
} else {
$User = Users::findOne(['id' => $userlogin->user_id]);
if (!count($User))
{
return null;
}
else {
$dbUser = [
'id' => $User->id,
];
return new static($dbUser);
}
}
}
在 Controller 中,我添加 behaviors()
如下。
public function behaviors()
{
$behaviors[] = [
'class' => \yii\filters\ContentNegotiator::className(),
'formats' => [
'application/json' => \yii\web\Response::FORMAT_JSON,
],
];
$behaviors['authenticator'] = [
'class' => HttpBearerAuth::className(),
];
return $behaviors;
}
当 API 未获得令牌或令牌无效时,它给出以下响应
{
"name": "Unauthorized",
"message": "You are requesting with an invalid credential.",
"code": 0,
"status": 401,
"type": "yii\web\UnauthorizedHttpException"
}
我想根据我的要求更改响应,如下所示。
{
"code": 401,
"name": "Unauthorized",
"is_logout": "Y",
"status": "error",
"message": "logout"
}
您可以使用 yii\web\Response
的 beforeSend
事件更改响应格式。
例如,在您的 api 控制器中添加以下方法:
public function init()
{
parent::init();
\Yii::$app->response->on(
\yii\web\Response::EVENT_BEFORE_SEND,
[$this, 'beforeResponseSend']
);
}
public function beforeResponseSend(\yii\base\Event $event)
{
/**
* @var \yii\web\Response $response
*/
$response = $event->sender;
if ($response->data['status'] == 401) {
$response->data = [
'code' => 401,
'name' => 'Unauthorized',
'is_logout' => 'Y',
'status' => 'error',
'message' => 'logout',
];
}
}
控制器的init
方法注册了beforeSend
事件。 beforeResponseSend
方法处理事件并更改响应格式。
如果你想在多个控制器中格式化响应,最好将事件处理程序放入自己的 class 例如
namespace app\components;
class ErrorResponseHelper
{
public static function beforeResponseSend(Event $event)
{
// ... formating code ...
}
}
并在config/web.php
return [
// ...
'components' => [
'response' => [
'class' => 'yii\web\Response',
'on beforeSend' => [
\app\components\ErrorResponseHelper::class,
'beforeResponseSend',
],
],
],
];
但是要小心这个解决方案,因为这样 \app\components\ErrorResponseHelper::beforeResponseSend
将在每个请求期间被调用。