Laravel 5如何验证路由参数?

JBP*_*JBP 27 routes laravel laravel-5 laravel-validation laravel-request

我想验证"表单请求"中的路由参数,但不知道如何操作.

下面是代码示例,我正在尝试:

路线

// controller Server
Route::group(['prefix' => 'server'], function(){
    Route::get('checkToken/{token}',['as'=>'checkKey','uses'=> 'ServerController@checkToken']);
});
Run Code Online (Sandbox Code Playgroud)

调节器

namespace App\Http\Controllers;


use App\Http\Controllers\Controller;

use Illuminate\Http\Request;
use App\Http\Requests;


class ServerController extends Controller {
    public function checkToken( \App\Http\Requests\CheckTokenServerRequest $request) // OT: - why I have to set full path to work??
        {   
            $token = Token::where('token', '=', $request->token)->first();      
            $dt = new DateTime; 
            $token->executed_at = $dt->format('m-d-y H:i:s');
            $token->save();

            return response()->json(json_decode($token->json),200);
        }
}
Run Code Online (Sandbox Code Playgroud)

CheckTokenServerRequest

namespace App\Http\Requests;

use App\Http\Requests\Request;

class CheckTokenServerRequest extends Request {

        //autorization

        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules()
        {

            return [
                'token' => ['required','exists:Tokens,token,executed_at,null']
            ];
        }

}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试验证一个简单的URL http:// myurl/server/checkToken/222时,我得到了响应: no " token " parameter set.

是否可以在单独的"表单请求"中验证参数,或者我必须在控制器中执行所有操作?

PS.对不起,我的英语不好.

Mar*_*łek 27

对此的方法是覆盖all()方法,CheckTokenServerRequest如下所示:

public function all() 
{
   $data = parent::all();
   $data['token'] = $this->route('token');
   return $data;
}
Run Code Online (Sandbox Code Playgroud)

编辑

以上解决方案适用于Laravel <5.5.如果您想在Laravel 5.5或更高版本中使用它,您应该使用:

public function all($keys = null) 
{
   $data = parent::all($keys);
   $data['token'] = $this->route('token');
   return $data;
}
Run Code Online (Sandbox Code Playgroud)

代替.


小智 6

如果您不想指定每个路由参数而只放置所有路由参数,您可以像这样覆盖:

Laravel < 5.5

public function all()
{
   return array_merge(parent::all(), $this->route()->parameters());
}
Run Code Online (Sandbox Code Playgroud)

Laravel 5.5 或更高版本

public function all($keys = null)
{
   // Add route parameters to validation data
   return array_merge(parent::all(), $this->route()->parameters());
}
Run Code Online (Sandbox Code Playgroud)


Sal*_*lar 5

表单请求验证器用于验证通过POST方法发送到服务器的HTML表单数据。最好不要将它们用于验证路由参数。路由参数主要用于从数据库中检索数据,因此为了确保您的令牌路由参数正确无误,请更改代码的这一行,从

$token = Token::where('token', '=', $request->token)->first();
Run Code Online (Sandbox Code Playgroud)

$token = Token::where('token', '=', $request->input(token))->firstOrFail();
Run Code Online (Sandbox Code Playgroud)

firstOrFail()是一个非常好的函数,如果用户插入了无效的令牌,它将向您的用户发送404。

您会收到,no " token " parameter set因为Laravel假设您的“令牌”参数是POST数据,但在您的情况下不是。

如果您坚持要验证“令牌”参数,则通过表单请求验证器将减慢您的应用程序的速度,因为您对数据库执行了两个查询,一个在这里

$token = Token::where('token', '=', $request->token)->first();
Run Code Online (Sandbox Code Playgroud)

还有一个在这里

return [
            'token' => ['required','exists:Tokens,token,executed_at,null']
        ];
Run Code Online (Sandbox Code Playgroud)

我建议同时使用firsOrFail进行验证检索


Mah*_*alt 5

覆盖all()Request对象上的函数,以自动将验证规则应用于URL参数

class SetEmailRequest
{

    public function rules()
    {
        return [
            'email'    => 'required|email|max:40',
            'id'       => 'required|integer', // << url parameter
        ];
    }

    public function all()
    {
        $data = parent::all();
        $data['id'] = $this->route('id');

        return $data;
    }

    public function authorize()
    {
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

在注入请求后,通常从控制器访问数据:

$setEmailRequest->email // request data
$setEmailRequest->id, // url data
Run Code Online (Sandbox Code Playgroud)