在 Yii2 中,我学会了创建 Rest API。我现在可以发布获取和更新数据。我最近添加了身份验证,我的令牌已被接受,但正在尝试从用户表中查找 useranme auth_key、password_hash 和电子邮件。我正在更新我的 Reading_schedule 表。 我目前正在使用邮递员来测试我的 Rest API 的 url 创建 一切都在没有身份验证的情况下正常工作,直到我最近在我的代码中添加了Basic Authentication。
即使我将身份验证密钥令牌添加到授权中,它现在也会在 Postman 上显示此消息
[
{
"field": "username",
"message": "Username cannot be blank."
},
{
"field": "auth_key",
"message": "Auth Key cannot be blank."
},
{
"field": "password_hash",
"message": "Password Hash cannot be blank."
},
{
"field": "email",
"message": "Email cannot be blank."
}
]
这是我的模块 v1 下的控制器
<?php
namespace app\modules\v1\controllers;
use yii\rest\ActiveController;
use yii\web\Controller;
/**
* ReadingSchedule controller for the `v1` module
*/
class ReadingScheduleController extends ActiveController
{
public $modelClass="app\models\ReadingSchedule";
public function behaviors() //override
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => \yii\filters\auth\CompositeAuth::class,
'authMethods' => [
\yii\filters\auth\HttpBearerAuth::class,
\yii\filters\auth\HttpBasicAuth::class,
[
'class' => \yii\filters\auth\CompositeAuth::class,
]
]
];
$behaviors['authenticator'] = [
'class' => \yii\filters\auth\HttpBasicAuth::class,
'auth' => [$this, 'auth']
];
return $behaviors;
}
public function auth($username, $password)
{
return \app\models\User::findOne(['login' => $username, 'password' => $password]);
}
}
这是我的用户模块,因为它指出我需要实现身份接口
<?php
namespace app\models;
use Yii;
use yii\web\IdentityInterface;
/**
* This is the model class for table "user".
*
* @property int $id
* @property string $username
* @property string $auth_key
* @property string|null $verification_token
* @property string $password_hash
* @property string|null $password_reset_token
* @property string $email
* @property int $status
* @property string $created_at
* @property string $updated_at
*/
class User extends \yii\db\ActiveRecord implements IdentityInterface
{
const STATUS_DELETED = 0;
const STATUS_INACTIVE = 9;
const STATUS_ACTIVE = 10;
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'user';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_INACTIVE, self::STATUS_DELETED]],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'username' => 'Username',
'auth_key' => 'Auth Key',
'verification_token' => 'Verification Token',
'password_hash' => 'Password Hash',
'password_reset_token' => 'Password Reset Token',
'email' => 'Email',
'status' => 'Status',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
public static function findIdentity($id)
{
return static::findOne($id);
}
public static function findIdentityByAccessToken($token, $type = null)
{
return static::findOne(['auth_key' => $token]);
}
public function getId()
{
return $this->id;
}
public function getAuthKey()
{
return $this->auth_key; // Updated case for property name
}
public function validateAuthKey($authKey)
{
return $this->auth_key === $authKey; // Updated case for property name
}
}
经过几个小时的研究,我尝试了 QueryParamAuth 作为示例身份验证。 我在使用 QueryParamAuth 的 Postman 中遇到的 422 数据验证错误消息可能是因为 即使我使用访问令牌进行身份验证,代码仍在尝试验证用户数据。以下是发生的情况以及解决方法:
错误原因:
Thw actionCreate 逻辑是为基于表单的身份验证而设计的,其中用户数据在请求正文中提交。它期望存在用户名、auth_key、password_hash 和电子邮件等字段。 QueryParamAuth 将访问令牌作为 URL 参数发送,而不是在请求正文中发送。 解决方案:
解决这个问题有两种主要方法:
1。 API 请求的单独逻辑:
创建一个单独的操作方法,专门用于使用 QueryParamAuth 处理 API 请求。 在这个新的操作方法中,从 URL 参数检索访问令牌(例如,$accessToken = Yii::$app->request->getQueryParam('access_token'))。 验证访问令牌(例如,在数据库中检查其有效性或使用令牌验证库)。 如果令牌有效,则继续创建阅读计划,无需验证用户数据。
2。 actionCreate 中的条件检查(修改方法):
修改现有的 actionCreate 逻辑以处理表单提交和 API 请求。 添加检查以查看请求方法是否为 POST 以及 URL 参数中是否存在访问令牌。 如果它是具有有效访问令牌的 API 请求,则绕过用户数据验证并继续创建阅读计划。否则,继续基于表单的验证逻辑。
这是使用条件检查方法修改后的actionCreate代码:
PHP
public function actionCreate()
{
$model = new ReadingSchedule();
$accessToken = Yii::$app->request->getQueryParam('access_token');
if ($this->request->isPost() && $accessToken) {
// API request with access token (bypass validation)
$user = // Retrieve user based on valid access token (implement logic)
if (!$user) {
return $this->asJson(['message' => 'Invalid access token'], 401); // Unauthorized
}
// ... proceed with creating reading schedule using user object ...
} else {
// Regular form submission (validate user data)
if ($model->load($this->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
}
return $this->render('create', [
'model' => $model,
]);
}
补充说明:
请记住实现基于有效访问令牌检索用户的逻辑($user = // 基于有效访问令牌检索用户(实现逻辑))。 根据您的具体需求调整错误处理(例如,返回 401 未经授权的响应)。
通过实现其中一种方法,您应该能够在 actionCreate 逻辑中使用 QueryParamAuth 处理表单提交和 API 请求。 API请求将绕过用户数据验证并依赖访问令牌进行身份验证。