Search code examples
laravel-5http-redirectunauthorized

Redirect if request authorization is failed in Laravel


I am trying to redirect request if authorization is failed for it. I have following code:

class ValidateRequest extends Request{
    public function authorize(){
        // some logic here...
        return false;
    }

    public function rules(){ /* ... */}

    public function failedAuthorization() {
        return redirect('safepage');
    }
}

By default I am redirected to the 403 error page, but I would like to specify some specific route. I noticed that method failedAuthorization() is run, but redirect() method does not work...

Previously this code worked well with Laravel 5.1 but I used forbiddenResponse() method to redirect wrong request. How can I fix it with new LTS version?


Solution

  • Looks like it is impossible to redirect() directly from the custom ValidateRequest class. The only solution that I found is create custom exception and than handle it in the Handler class. So, now it works with following code:

    Update: The method redirectTo() was updated to make solution work on Laravel 6.x and higher

    app/Requests/ValidateRequest.php

    class ValidateRequest extends Request{
        public function authorize(){
            // some logic here...
            return false;
        }
    
        public function rules(){
            return [];
        }
    
        public function failedAuthorization() {
            $exception = new NotAuthorizedException('This action is unauthorized.', 403);
            
            throw $exception->redirectTo("safepage");
        }
    }
    

    app/Exceptions/NotAuthorizedException.php

    <?php
    
    namespace App\Exceptions;
    
    use Exception;
    
    class NotAuthorizedException extends Exception
    {
        protected $route;
    
        public function redirectTo($route) {
            $this->route = $route;
        
            abort(Redirect::to($route));
        }
        
        public function route() {
            return $this->route;
        }
    }
    

    and app/Exceptions/Handler.php

    ...
    public function render($request, Exception $exception){
        ...
    
        if($exception instanceof NotAuthorizedException){
                return redirect($exception->route());
            }
    
        ...
    }
    

    So, it works, but much more slower than I expected... Simple measuring shows that handling and redirecting take 2.1 s, but with Laravel 5.1 the same action (and the same code) takes only 0.3 s

    Adding NotAuthorizedException::class to the $dontReport property does not help at all...

    Update

    It runs much more faster with php 7.2, it takes 0.7 s