web-dev-qa-db-fra.com

Laravel 5 comment valider les paramètres de l'itinéraire?

Je veux valider les paramètres de l'itinéraire dans la "demande de formulaire" mais je ne sais pas comment le faire.

Voici l'exemple de code, j'essaie avec:

Route

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

Contrôleur

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

}

Mais quand j'essaye de valider une simple URL http: // myurl/server/checkToken/222 , j'obtiens la réponse: no " token " parameter set.

Est-il possible de valider les paramètres dans une "demande de formulaire" séparée, ou dois-je tout faire dans un contrôleur?

ps. Désolé pour mon mauvais anglais.

28
JBP

La manière pour cela est de remplacer la méthode all() pour CheckTokenServerRequest comme ceci:

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

MODIFIER

La solution ci-dessus fonctionne en Laravel <5.5. Si vous souhaitez l'utiliser dans Laravel 5.5 ou supérieur, vous devez utiliser:

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

au lieu.

25
Marcin Nabiałek

Remplacez la fonction all() sur l'objet Request pour appliquer automatiquement des règles de validation aux paramètres d'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;
    }
}

Accédez aux données normalement depuis le contrôleur comme ceci, après avoir injecté la requête:

$setEmailRequest->email // request data
$setEmailRequest->id, // url data
5
Mahmoud Zalt

Les validateurs de demande de formulaire sont utilisés pour valider données de formulaire HTML qui sont envoyées au serveur via méthode [~ # ~] post [~ # ~]. Il est préférable de ne pas les utiliser pour valider les paramètres de l'itinéraire. les paramètres de route sont principalement utilisés pour récupérer les données de la base de données, afin de vous assurer que votre paramètre de route de jeton est correct, changez cette ligne de votre code

$token = Token::where('token', '=', $request->token)->first();

à

$token = Token::where('token', '=', $request->input(token))->firstOrFail();

firstOrFail () est une très bonne fonction, il envoie 404 à votre utilisateur, si l'utilisateur insère un jeton non valide.

vous obtenez no " token " parameter set parce que Laravel suppose que votre paramètre "token" est une donnée POST qui ne l'est pas dans votre cas).

si vous insistez pour valider votre paramètre "token", par les validateurs de demande de formulaire, vous allez ralentir votre application, car vous effectuez deux requêtes sur votre base de données, une ici

$token = Token::where('token', '=', $request->token)->first();

et un ici

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

Je suggère d'utiliser firsOrFail pour faire à la fois validation et récupération à la fois.

5
Salar

Un trait peut rendre cette validation relativement automagique.

Trait

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

}

Usage

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

Si vous ne souhaitez pas spécifier chaque paramètre de route et simplement mettre tous les paramètres de route, vous pouvez remplacer comme ceci:

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

Pour \App\Http\Requests\CheckTokenServerRequest vous pouvez ajouter use App\Http\Requests\CheckTokenServerRequest; au sommet.
Si vous passez le token par url vous pouvez l'utiliser comme une variable dans 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);

ou

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

ou laissez la plupart de la logique all en place et remplacez la méthode input de 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 possède une méthode validationData() qui définit les données à utiliser pour la validation. Il suffit donc de remplacer celui-ci avec les paramètres de route dans votre classe de demande de formulaire:

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

Vous venez de manquer le trait de soulignement avant le jeton. Remplacer par

_jeton

partout où vous le comparez au formulaire généré par laravel.

public function rules()
{

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