我有一个
language
参数,需要发送到我的文档端点。所以我必须验证用户是否在他的 GET 请求中发送了这个参数。
在我的模型中制定规则没有做任何事情:
public function rules()
{
return [
[['language'], 'required'],
];
}
因此我尝试过这个:
我已经创建了ParamsValidator类:
我正在控制器中调用其
validate()
方法 init()
方法:
public function init()
{
$this->_params = Yii::$app->request->queryParams;
$validator = new ParamsValidator();
$validator->validate($this->_params);
}
还有这种工作。代码有效,但我得到了丑陋的回应。我得到的不是漂亮的 JSON 响应,而是一堆像这样开始的 html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Unprocessable entity (#422)</title>
<style>
body {
font: normal 9pt "Verdana";
color: #000;
background: #fff;
}
我想要一些不错的 JSON 响应,而不是这个 html:
{
"name": "Forbidden",
"message": "You are not authorized to do this.",
"code": 0,
"status": 403,
"type": "yii\\web\\ForbiddenHttpException"
}
您看到的这个漂亮的 JSON 错误是由以下人员造成的:
$behaviors['authenticator'] = [
'class' => HttpBasicAuth::className(),
'auth' => [$this, 'authenticate']
];
但显然我的验证器没有这样做。
问题:
一个简单的选择是通过在控制器中添加以下内容来覆盖 ActiveController::checkAccess 方法:
public function checkAccess($action, $model = null, $params = [])
{
if ($action === 'index' or $action === 'view')
{
$params = Yii::$app->request->queryParams;
if (!isset($params['language'])) {
throw new \yii\web\ForbiddenHttpException('You are not authorized to do this.');
}
}
}
如果您需要在模型级别执行此操作,则需要使用 addError() 方法,而不是直接抛出错误。您的模型实例将在调用其 validate 方法时保存它。然后在你的操作中你可以简单地返回它。它将被序列化,并且错误将以正确的格式输出。有很多方法可以实现这一目标。一个简单的示例可能是使用 load 方法在验证模型之前将查询和正文参数传递给模型(可能需要场景):
$queryParams = Yii::$app->request->queryParams;
$bodyParams = Yii::$app->request->bodyParams;
$params = array_merge($queryParams,$bodyParams );
$model = new $modelClass;
$model->load($params , '');
if ($model->validate() === false) return $model;
else {
// do whatever you need
}