【问题标题】:Request validation allways passes on Laravel using Dingo/Api请求验证总是使用 Dingo/Api 在 Laravel 上传递
【发布时间】:2016-05-04 19:58:54
【问题描述】:

我正在使用dingo/api 包。

控制器:

public function register(RegisterUserRequest $request)
{
    dd('a');
}

例如,电子邮件字段是必需的:

<?php namespace App\Http\Requests;


class RegisterUserRequest extends Request
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => 'required'
        ];
    }
}

所以我发送了一个没有电子邮件的请求,但仍然收到“a”响应。

我也尝试过扩展Dingo\Api\Http\Request 而不是App\Http\Request,但还是一样。

【问题讨论】:

    标签: php laravel laravel-5.1 dingo-api


    【解决方案1】:

    根据Wiki

    您必须重载 failedValidation 和 failedAuthorization 方法。 这些方法必须抛出上述异常之一,而不是 Laravel 抛出的响应 HTTP 异常。

    如果你看一下 Dingo\Api\Http\FormRequest.php,你会看到:

    class FormRequest extends IlluminateFormRequest
    {
        /**
         * Handle a failed validation attempt.
         *
         * @param \Illuminate\Contracts\Validation\Validator $validator
         *
         * @return mixed
         */
        protected function failedValidation(Validator $validator)
        {
            if ($this->container['request'] instanceof Request) {
                throw new ValidationHttpException($validator->errors());
            }
    
            parent::failedValidation($validator);
        }
    
        /**
         * Handle a failed authorization attempt.
         *
         * @return mixed
         */
        protected function failedAuthorization()
        {
            if ($this->container['request'] instanceof Request) {
                throw new HttpException(403);
            }
    
            parent::failedAuthorization();
        }
    }
    

    因此,您需要适当地更改方法的名称,并让它们抛出适当的异常,而不是返回布尔值。

    【讨论】:

      【解决方案2】:

      要让 Dingo 完全使用 FormRequest,根据经验(以及来自 this Issue),您必须使用 Dingo's 表单请求,即 Dingo\Api\Http\FormRequest;,所以你会有类似的东西:

      <?
      namespace App\Http\Requests;
      use Dingo\Api\Http\FormRequest;
      use Symfony\Component\HttpKernel\Exception\HttpException;
      
      
      class RegisterUserRequest extends FormRequest
      {
          /**
           * Determine if the user is authorized to make this request.
           *
           * @return bool
           */
          public function authorize()
          {
              return true;
          }
      
          /**
           * Get the validation rules that apply to the request.
           *
           * @return array
           */
           public function rules()
           {
              return [
                  'email' => 'required'
              ];
           }
          // In case you need to customize the authorization response
          // although it should give a general '403 Forbidden' error message
          /**
           * Handle a failed authorization attempt.
           *
           * @return mixed
           */
           protected function failedAuthorization()
           {
               if ($this->container['request'] instanceof \Dingo\Api\Http\Request) {
                  throw new HttpException(403, 'You cannot access this resource'); //not a user?
               }
      
           }
      }
      

      PS:这是在 Laravel 5.2 上测试的。*

      希望对你有帮助:)

      【讨论】:

        【解决方案3】:

        当您在 Dingo API 设置下运行验证函数时,您需要显式调用验证函数,尝试这样的操作(对于 L5.2):

        可能还有一些额外的提供者

        ...
        Illuminate\Validation\ValidationServiceProvider::class,
        Dingo\Api\Provider\LaravelServiceProvider::class,
        ...
        

        别名

        ...
        'Validator' => Illuminate\Support\Facades\Validator::class,
        ...
        

        我也很确定你真的不想按照这里和那里的建议在下面使用它,它会期望表单(编码)输入,并且也可能会像它所期望的那样在 CSRF 令牌上失败,所以它验证后将立即失败(表单输入)。但请务必在此开/关情况下测试行为。

        use Dingo\Api\Http\FormRequest;
        

        制作标题:

        use Illuminate\Http\Request;
        use Illuminate\Http\Response;
        use App\Http\Requests;
        use App\Http\Controllers\Controller;
        
        use Dingo\Api\Exception\ValidationHttpException;
        use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
        
        /* This can be a tricky one, if you haven't split up your 
         dingo api from the http endpoint, there are plenty 
         of validators around in laravel package 
        */
        
        use Validator; 
        

        然后是实际代码(如果您遵守 cors 标准, 这应该是一个 POST 并且通常转换为存储请求)

        ...
        /**
        * Store a newly created resource in storage.
        *
        * @param  \Illuminate\Http\Request  $request
        * @return \Illuminate\Http\Response
        */
        public function register(RegisterUserRequest $request) {
            $validator = Validator::make($request->all(), $this->rules());
            if ($validator->fails()) {
                $reply = $validator->messages();
                return response()->json($reply,428);
            };
            dd('OK!');
        };
        ...
        
        /**
        * Get the validation rules that apply to the request.
        *
        * @return array
        */
        public function rules()
        {
            return [
                    'email'   => 'required'
                    // or/and 'userid'     => 'required'
            ];
        }
        

        这将使您返回您期望从验证器获得的响应。如果您将其与预生成的表单一起使用,则不需要此修复,验证器将自动启动。 (不在 Dingo Api 下)。

        您可能还需要 composer.json 中的这些

            "dingo/api": "1.0.*@dev",
            "barryvdh/laravel-cors": "^0.7.1",
        

        这是未经测试的,我花了 2 天时间才弄清楚这一点,但我有一个单独的命名空间用于特定于 API 并通过中间件进行身份验证。成功

        【讨论】:

          猜你喜欢
          • 2017-06-02
          • 2016-03-07
          • 2017-05-17
          • 2017-10-01
          • 2019-02-19
          • 2017-06-02
          • 2017-01-19
          • 2018-09-13
          • 2023-03-14
          相关资源
          最近更新 更多