「フォームリクエスト」でルートパラメータを検証したいのですが、方法がわかりません。
以下はコードサンプルです、私は試しています:
ルート
// controller Server
Route::group(['prefix' => 'server'], function(){
Route::get('checkToken/{token}',['as'=>'checkKey','uses'=> 'ServerController@checkToken']);
});
コントローラー
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);
}
}
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']
];
}
}
しかし、単純なURL http:// myurl/server/checkToken/222 を検証しようとすると、応答が返されます:no " token " parameter set
。
個別の「フォームリクエスト」でパラメーターを検証することは可能ですか、それともすべてコントローラーで行う必要がありますか?
ps。英語が下手でごめんなさい。
これを行う方法は、CheckTokenServerRequest
のall()
メソッドを次のようにオーバーライドすることです。
public function all()
{
$data = parent::all();
$data['token'] = $this->route('token');
return $data;
}
[〜#〜]編集[〜#〜]
上記のソリューションはLaravel <5.5で機能します。 Laravel 5.5以降で使用する場合は、次のように使用する必要があります。
public function all($keys = null)
{
$data = parent::all($keys);
$data['token'] = $this->route('token');
return $data;
}
代わりに。
Requestオブジェクトのall()
関数をオーバーライドして、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;
}
}
リクエストを挿入した後、このようにコントローラから通常データにアクセスします:
$setEmailRequest->email // request data
$setEmailRequest->id, // url data
フォームリクエストバリデーターは[〜#〜] post [〜#〜]メソッドを介してサーバーに送信されるHTMLフォームデータを検証するために使用されます。ルートパラメータの検証には使用しないことをお勧めします。ルートパラメータは主にデータベースからデータを取得するために使用されるため、トークンのルートパラメータが正しいことを確認するには、次のコード行を変更します。
$token = Token::where('token', '=', $request->token)->first();
に
$token = Token::where('token', '=', $request->input(token))->firstOrFail();
firstOrFail()は非常に優れた関数であり、ユーザーが無効なトークンを挿入すると、404がユーザーに送信されます。
あなたはno " token " parameter set
は、Laravelは、「トークン」パラメータがPOSTデータであると想定しているため、そうではないことを前提としています。
「トークン」パラメーターの検証を主張する場合、フォームリクエストバリデーターによってアプリケーションの速度が低下します。これは、データベースに対して2クエリを実行するためです。
$token = Token::where('token', '=', $request->token)->first();
そしてここに一つ
return [
'token' => ['required','exists:Tokens,token,executed_at,null']
];
firsOrFailを使用して、validatingとretrievingの両方を同時に実行することをお勧めします。
特性によって、この検証は比較的自動化されます。
特性
<?php
namespace App\Http\Requests;
/**
* Class RouteParameterValidation
* @package App\Http\Requests
*/
trait RouteParameterValidation{
/**
* @var bool
*/
private $captured_route_vars = false;
/**
* @return mixed
*/
public function all(){
return $this->capture_route_vars(parent::all());
}
/**
* @param $inputs
*
* @return mixed
*/
private function capture_route_vars($inputs){
if($this->captured_route_vars){
return $inputs;
}
$inputs += $this->route()->parameters();
$inputs = self::numbers($inputs);
$this->replace($inputs);
$this->captured_route_vars = true;
return $inputs;
}
/**
* @param $inputs
*
* @return mixed
*/
private static function numbers($inputs){
foreach($inputs as $k => $input){
if(is_numeric($input) and !is_infinite($inputs[$k] * 1)){
$inputs[$k] *= 1;
}
}
return $inputs;
}
}
使用法
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyCustomRequest extends FormRequest{
use RouteParameterValidation;
/**
* 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 [
//
'any_route_param' => 'required'//any rule(s) or custom rule(s)
];
}
}
各ルートパラメータを指定せずにすべてのルートパラメータを配置する場合は、次のようにオーバーライドできます。
public function all()
{
return array_merge(parent::all(), $this->route()->parameters());
}
ために \App\Http\Requests\CheckTokenServerRequest
あなたは付け加えられます use App\Http\Requests\CheckTokenServerRequest;
頂点で。token
をurl
で渡すと、controller
の変数のように使用できます。
public function checkToken($token) //same with the name in url
{
$_token = Token::where('token', '=', $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);
}
$request->merge(['id' => $id]);
...
$this->validate($request, $rules);
または
$request->merge(['param' => $this->route('param')]);
...
$this->validate($request, $rules);
または、all
ロジックのほとんどをそのままにして、input
メソッドをtrait \Illuminate\Http\Concerns\InteractsWithInput
からオーバーライドします
/**
* Retrieve an input item from the request.
*
* @param string|null $key
* @param string|array|null $default
* @return string|array|null
*/
public function input($key = null, $default = null)
{
return data_get(
$this->getInputSource()->all() + $this->query->all() + $this->route()->parameters(), $key, $default
);
}
FormRequestには、検証に使用するデータを定義するメソッドvalidationData()
があります。ですから、フォームリクエストクラスのルートパラメータでそれをオーバーライドしてください:
/**
* Use route parameters for validation
* @return array
*/
protected function validationData()
{
return $this->route()->parameters();
}
トークンの前にアンダースコアがない。と置換する
_トークン
あなたがそれをlaravelによって生成されたフォームに対してチェックするところはどこでも。
public function rules()
{
return [
'_token' => ['required','exists:Tokens,token,executed_at,null']
];