2016-04-15 36 views
1

我有一個language參數,需要被髮送到我的文檔端點。所以我必須驗證用戶在他的GET請求中發送了這個參數。如何驗證來自Yii2 RESTful服務中GET請求的參數

使在我的模型規則沒有做任何事情:

public function rules() 
{ 
    return [ 
     [['language'], 'required'], 
    ]; 
} 

因爲我已經試過這一點:

1)我已經創建ParamsValidator類:

<?php 
namespace app\modules\v1\components; 

use yii\web\UnprocessableEntityHttpException; 
use yii\base\Component; 
use Yii; 

/** 
* Class that is responsible for validating input params. 
*/ 
class ParamsValidator extends Component 
{ 
    public function validate($params) 
    { 
     if (!isset($params['language'])) { 
      throw new UnprocessableEntityHttpException("Language parameter is required"); 
     } 
    } 
} 

我我在我的控制器裏調用它的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響應:

{ 
    "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'] 
]; 

但很明顯我的驗證器沒有這樣做。

問題:

1)如何驗證通過GET請求來的參數?
2)如果我的方法是正確的,如何得到這個不錯的JSON錯誤響應?

回答

1

一個簡單的選擇是通過增加這裏面控制器重寫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方法驗證之前,通過查詢和身體PARAMS到模型(場景可能需要):

$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 
} 
+0

你缺少右大括號'如果(isset($ PARAMS [ '語言']))'。無論如何,這工作,但爲什麼checkAccess和爲什麼ForbiddenHttpException?調用參數驗證進行訪問檢查對我來說似乎沒有語義。或者我錯了? – offline

+0

你可以拋出任何你需要的錯誤,想法是你的錯誤信息將被序列化,因爲你的控制器的內容抑制器過濾器將被應用。我會親自在模型層面做到這一點。檢查我的更新 –

+0

好吧,當我這樣做,我得到驗證,並且我得到錯誤:'$ model = new $ this-> modelClass; $ queryParams = Yii :: $ app-> request-> queryParams; $ bodyParams = Yii :: $ app-> request-> bodyParams; $ params = array_merge($ queryParams,$ bodyParams); $ model-> load($ params,''); (!$ model-> validate()){ return $ model; }'但錯誤格式爲:[ 「字段」:「語言」, 「消息」:「語言不能爲空。 } ]'並且我想JSON響應就像我在問題中所述。它需要有狀態 – offline