Laravel 5.3 policies how to redirect unauthorized users
Asked Answered
D

4

14

I can't find it on the documentation. How to redirect unauthorized user?

RolePolicy.php

class RolePolicy
{
    use HandlesAuthorization;

    public function manageRoles(User $user)
    {
        return $user->isAdmin();
    }
}

RolesController.php

function __construct()
{
    $this->authorize('manageRoles', Role::class);
}

Thanks in advance

Didst answered 17/9, 2016 at 14:11 Comment(1)
Why it gets down vote? :( what's wrong?Didst
D
10

You can modify file app\Exceptions\Handler.php

on the render function:

public function render($request, Exception $e)
{

    /**modified part**/  
    if ($request->wantsJson()) {
        return response([
            'success' => false,
            'message' => $e->getMessage()
        ], 404);
    }

    if ($e instanceof AuthorizationException) {
        return redirect('path');

        //or simply
        return view('errors.forbidden');
        //but this will return an OK, 200 response.
    }
    /**end of modified part**/

    return parent::render($request, $e);
}

If you want to put a 403, use helper function response(). You can see the documentation for responses here https://laravel.com/docs/master/responses

Basically you can use the solution to play with more options. But the easiest way is just to create a view file: errors/403.blade.php and that view will automatically load when you hit unauthorized exceptions. The same will work for 404 not found, just create the 404.blade.php.

Dorladorlisa answered 28/9, 2016 at 4:54 Comment(0)
D
3

As far as I know, this is no different in Laravel 5.3 as it is in any version of Laravel 5.

There is a route middleware named auth that refers to App\Http\Middleware\Authenticate (defined in app/http/Kernel.php)

In this class:

public function handle($request, Closure $next, $guard = null)
{
    if (Auth::guard($guard)->guest()) {
        if ($request->ajax()) {
            return response('Unauthorized.', 401);
        } else {
            return redirect()->guest('login');
        }
    }

    return $next($request);
}

This auth middleware can be applied to routes that require authentication.

Read more about middleware here: https://laravel.com/docs/5.3/middleware

Read more about Authentication here: https://laravel.com/docs/5.3/authentication

Digitoxin answered 17/9, 2016 at 14:58 Comment(2)
but I want to authorize via controllers laravel.com/docs/5.3/authorization#via-controller-helpersDidst
Check this laracasts.com/discuss/channels/laravel/…Pericope
C
0

Use Laravel Gates, In your controller methods. For example:

public function update(Role $role){

if(\Gates::allows('manageRoles',$role)) {

return redirect()->back()->with('status','Success');

}

However, i personally think its too troublesome to set a redirect page for every controller action. If the action is denied cos the user manipulated the url and not because some prerequisites have not be completed then a straight 404 page with a home button should suffice.

Like what the answer above says, its much better and easier to just use Laravel responses, call the error page you want and pass in a custom message.

like this answer from another thread:

return response("User can't perform this action.", 401);

https://mcmap.net/q/497301/-laravel-5-custom-abort-message

Cassey answered 14/6, 2019 at 5:32 Comment(0)
S
0

I implemented some logic, wish it helps someone.
First, call the method for example $this->anonymouslyAuthorize($model)
in a method in your for example PostController

public function show(Post $post)
{
    $this->anonymouslyAuthorize($post);

    // The user is authorized.
}

in your base controller which leaves in Controllers directory add this method.

public function anonymouslyAuthorize($model)
{
    Auth::user()->can('see', $model);
}

in AuthServiceProvider in the boot method define this Gate.

public function boot()
{
    $this->registerPolicies();

    Gate::define('see', function ($user, $model) {
        if ($user->id !== $model->user_id) {
            abort(404);
        }
    });
}
Strontian answered 26/1, 2020 at 20:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.