Modify input in laravel middleware

Victor picture Victor · Nov 28, 2015 · Viewed 7.9k times · Source

Some service makes HTTP request to my site and passes some input. This input has a little bit wrong structure for me, so I'm trying to modify it.

I made a middleware and attached this middleware to my route. The handle method looks like this:

public function handle($request, Closure $next)
{
    $input = $request->all();

    // Input modification

    $request->replace($input);
    \Log::info($request->all()); // Shows modified request

    return $next($request);
}

However in my controller I got old input. Also I'm a little bit confused since I also use FormRequest, and as I realize these two requests are different entities. Then how can I modify the input in the middleware?

Answer

Marcin Nabiałek picture Marcin Nabiałek · Nov 29, 2015

I don't know what's the exact problem in your case but I'll show you what I did to make it work and it might solve your problem:

app/Http/Middleware/TestMiddleware.php

<?php namespace App\Http\Middleware;

use Closure;

class TestMiddleware
{

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $input = $request->all();

        if (isset($input['mod'])) {
            list($input['int'], $input['text']) = explode('-', $input['mod']);
            unset($input['mod']);
            // Input modification
            $request->replace($input);

            \Log::info($request->all()); // Shows modified request
        }

        return $next($request);
    }

}

app/Http/Kernel.php

protected $middleware = [
    'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
    'Illuminate\Cookie\Middleware\EncryptCookies',
    'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
    'Illuminate\Session\Middleware\StartSession',
    'Illuminate\View\Middleware\ShareErrorsFromSession',
    'App\Http\Middleware\VerifyCsrfToken',
    Middleware\TestMiddleware::class, // this line added
];

app/Http/routes.php

 Route::get('/test', ['uses' => 'TestController@index']);

app/Http/Requests/SampleRequest.php

<?php namespace App\Http\Requests;

class SampleRequest extends Request
{        
    public function rules()
    {
        return [
            'int'              =>
                [
                    'required',
                    'integer'
                ],
            'text' => [
                'max: 5',
            ]
        ];
    }
}

app/Http/Controllers/TestController.php

<?php namespace App\Http\Controllers;

use App\Http\Requests;


class TestController extends \Illuminate\Routing\Controller
{

    public function index(Requests\SampleRequest $request)
    {
       dd($request->all());

    }
}

In console I've run composer dump-autoload.

Now when I run the following url:

http://testproject.app/test?mod=23-tav

I'm getting in controller from dd:

array:2 [▼
  "text" => "tav"
  "int" => "23"
]

as expected and when I run for example http://testproject.app/test?mod=abc-tav I'm being redirected to mainpage in my case because data doesn't pass validation from SampleRequest (int is not integer)