Prevent redirect to homepage after invalid in Laravel
Asked Answered
P

5

29

I'm developing a RESTful API with Laravel 5.3, so I'm testing some functions and request with my controllers. One thing I need to do is validate the request that my user sends before add a field in my database, so, I use a custom FormRequest to validate it.

When I tested my API in Postman and send my invalid request, response redirect me to homepage. After reading documentation, I found the following statement

If validation fails, a redirect response will be generated to send the user back to their previous location. The errors will also be flashed to the session so they are available for display. If the request was an AJAX request, a HTTP response with a 422 status code will be returned to the user including a JSON representation of the validation errors.

How can I prevent this? Or there is a AJAX mode in Postman? Any suggestion?

Preemie answered 2/9, 2016 at 16:26 Comment(0)
P
98

Also this can be achieved without overriding any function. Laravel is built to support both Json & normal pages. Please change your settings in postman and set Accept to application/json like below enter image description here

Laravel is SMART ;-)

Purposeless answered 11/11, 2017 at 6:27 Comment(4)
can you please share the link if this thing is documented in laravel documentation ? Its really helpful.Calves
how can we force that if request doesnt contain any accept header also working in apisHacienda
Wow. This works for me. Never thought about that. That's why laravel security is awesome.Ripley
This stopped me going down a rabbit hole! The more I start to use Laravel the more I start to love itWorkmanlike
A
11

I faced same problem in Laravel 8. In your request class, you can override failedValidation method.

<?php

...
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;


class RegisterRequest extends FormRequest
{

    ...

    protected function failedValidation(Validator $validator)
    {
        throw new HttpResponseException(response()->json(['errors' => $validator->errors()], 422));
    }

    ...


}
Alvarado answered 30/9, 2021 at 18:24 Comment(0)
A
10

Your custom FormRequest extends Illuminate\Foundation\Http\FormRequest. Within is a function that performs the redirect called response(). Simply override this function within your custom FormRequest to change how invalid validations are responded to.


namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\JsonResponse;

class CustomFormRequest extends FormRequest
{
    /**
     * Custom Failed Response
     *
     * Overrides the Illuminate\Foundation\Http\FormRequest
     * response function to stop it from auto redirecting
     * and applies a API custom response format.
     *
     * @param array $errors
     * @return JsonResponse
     */
    public function response(array $errors) {

        // Put whatever response you want here.
        return new JsonResponse([
            'status' => '422',
            'errors' => $errors,
        ], 422);
    }
}
Asgard answered 7/11, 2016 at 22:46 Comment(0)
V
0

In Laravel 10 you have a few ways to achieve this:

Named routes

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ExampleRequest extends FormRequest
{

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        
       /**
        * The route to redirect to if validation fails.
        */
        $this->redirectRoute = 'named.example.route';
    
        return [
            //User inputs => validation rules 
        ];
    }
}

Named routes with parameters

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ExampleRequest extends FormRequest
{

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {
        $this->redirect = route(
            'named.example.route',
            ['example_param' => $this->param_value]
        );
        return [
            //User inputs => validation rules 
        ];
    }
}

Controller Actions

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ExampleRequest extends FormRequest
{

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {

       /**
        * The controller action to redirect to if validation fails.
        */
        $this->redirectAction = "ExampleController@exampleAction";

        return [
            //User inputs => validation rules 
        ];
    }
}

Return Back

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ExampleRequest extends FormRequest
{

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, mixed>
     */
    public function rules()
    {

        $this->redirect = url()->previous();

        return [
            //User inputs => validation rules 
        ];
    }
}
Vltava answered 22/2 at 16:33 Comment(0)
P
0

Sorry for necroing this but anyone in 2024 looking for a good solution can take a note from the accepted answer and use that with a middleware:

class EnsureAPIJsonHeaders
{
    /**
     * Handle an incoming request.
     *
     * @param Closure(Request): (Response) $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        // If request is to /api/*, set the Accept header to application/json
        if (str_starts_with($request->path(), 'api/')) {
            $request->headers->set('Accept', 'application/json');
        }

        return $next($request);
    }
}

You should of course modify the url that it checks on.

This is registered in the Kernel's api-middleware group, and will apply on any request, providing that you use that middleware group on your requests.

Pneumatics answered 21/4 at 16:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.