web-dev-qa-db-ja.com

Laravel 5ルートパラメータを検証する方法は?

「フォームリクエスト」でルートパラメータを検証したいのですが、方法がわかりません。

以下はコードサンプルです、私は試しています:

ルート

// 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。英語が下手でごめんなさい。

28
JBP

これを行う方法は、CheckTokenServerRequestall()メソッドを次のようにオーバーライドすることです。

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;
}

代わりに。

25

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
5
Mahmoud Zalt

フォームリクエストバリデーターは[〜#〜] 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を使用して、validatingretrievingの両方を同時に実行することをお勧めします。

5
Salar

特性によって、この検証は比較的自動化されます。

特性

<?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)
        ];
    }
}
2
Tarek Adam

各ルートパラメータを指定せずにすべてのルートパラメータを配置する場合は、次のようにオーバーライドできます。

public function all()
{
    return array_merge(parent::all(), $this->route()->parameters());
}
1
mk_

ために \App\Http\Requests\CheckTokenServerRequest あなたは付け加えられます use App\Http\Requests\CheckTokenServerRequest; 頂点で。
tokenurlで渡すと、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);
}
1
Hoàng Đăng
$request->merge(['id' => $id]);
...
$this->validate($request, $rules);

または

$request->merge(['param' => $this->route('param')]);
...
$this->validate($request, $rules);
0
Rene Berwanger

または、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
        );
    }
0
Paul Rysevets

FormRequestには、検証に使用するデータを定義するメソッドvalidationData()があります。ですから、フォームリクエストクラスのルートパラメータでそれをオーバーライドしてください:

    /**
     * Use route parameters for validation
     * @return array
     */
    protected function validationData()
    {
        return $this->route()->parameters();
    }
0

トークンの前にアンダースコアがない。と置換する

_トークン

あなたがそれをlaravelによって生成されたフォームに対してチェックするところはどこでも。

public function rules()
{

    return [
        '_token' => ['required','exists:Tokens,token,executed_at,null']
    ];
0
Cristo