Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Roles with laravel 5, how to allow only admin access to some root

Tags:

php

laravel-5

I follow this tutorial : https://www.youtube.com/watch?v=kmJYVhG6UzM Currently I can check in my blade if user is a admin or not like this:

{{ Auth::user()->roles->toArray()[0]['role'] }}
HI ADMIN
@endif

How can I make my route only available for admin user?

like image 599
Vladimir Djukic Avatar asked Mar 15 '15 13:03

Vladimir Djukic


2 Answers

You need to create a middleware for your route.

Use: php artisan make:middleware AdminMiddleware.

You will find in your middleware folder a new file with this name.

Put your logic in your middleware, e.g.

public function handle($request, Closure $next)
{
    if(Auth::check())
    {
        return $next($request);
    }
    else
    {
        return view('auth.login')->withErrors('You are not logged in');
    }

}

Once you have done your logic in your middleware, you can either call it in the route or make the middleware apply to all routes.

If you want to add it to all routes, go to Kernel.php and add it to the $middleware array, e.g.

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',
    'App\Http\Middleware\AdminMiddleware',
];

If you want to add it to specific routes only, add it to the $routeMiddleware variable and add the alias to the route. E.g.

protected $routeMiddleware = [
    'auth' => 'App\Http\Middleware\Authenticate',
    'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
    'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
    'admin' => 'App\Http\Middleware\AdminMiddleware',
];

You can then add it to a route, as a filter, e.g.

Route::get('admin/profile', ['middleware' => 'admin', function()
{

}]);

For additional info visit the docs:

http://laravel.com/docs/master/middleware

EDIT

An improvement on this would be to use variadic functions which was introduced in PHP 5.6

http://php.net/manual/en/migration56.new-features.php

Instead of having to make a middleware for each permission set you can do the following

PermissionMiddleware

namespace App\Http\Middleware;

use Closure;
use \App\Models\Role;
class PermissionMiddleware
{
    // Pass parameters to this middleware
    public function handle($request, Closure $next, ...$permitted_roles)
    {

        //Get a users role
        $role = new Role;
        $role_name = $role->getUserRoleByName();
        foreach($permitted_roles as $permitted_role) {
            if($permitted_role == $role_name) {
                return $next($request);
            }
        }
        return redirect()->back()->withErrors('You do not have the required permission');

    }
}

Notice the ...$permitted_roles

Route::get('admin/profile', ['middleware' => 'PermissionMiddleware:Admin,Marketing', function()
{

}]);

You can now specify as many roles as required for one middleware rather than creating multiple by using middleware parameters

Docs https://laravel.com/docs/5.3/middleware#middleware-parameters

like image 77
Chris Townsend Avatar answered Oct 11 '22 15:10

Chris Townsend


Let's assume you have a column in your users table with isAdmin name which has a default value of 0 (false)

You can give special access using middleware in laravel like you give access to logged in users using auth middleware in laravel. Now you need to create a middleware using the command :

php artisan make:middleware AdminMiddleware

In your Kernel.php you need to add this line to protected $routeMiddleware

'admin' => \App\Http\Middleware\AdminMiddleware::class,

In your middleware folder you have the AdminMiddleware file. In that you need to put your logic In this case this is how it might look like depending upon you

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RoleMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        if(Auth::user()->isAdmin == '1') // is an admin
        {
            return $next($request); // pass the admin
        }

        return redirect('/'); // not admin. redirect whereever you like

    }
}

Now in your route you have to pass the url using this middleware Here is how it might look like

Route::get('/iamanadmin', ['middleware' => 'admin', function() {
    return view('iamanadmin');
}]);
like image 29
Koushik Das Avatar answered Oct 11 '22 16:10

Koushik Das