Laravel 5.2 user roles

Laravel 5.2 has authentication integrated. You just have to run php artisan make:auth and you have all you need. But how can we create user roles?

There are a lot of packages out there, some of them supports Laravel 5.2, but personally I did not find anything "good". Taylor Otwell said he will make a feature/package with permissions. See here. But until then ... how can we make this work?

The simplest way is to create a middleware and check if the user has the admin role. For this, we can use an "is_admin" flag on the users table. So the first step is to update the users table migration, which was created by default.

<?php

use Illuminate\Database\Schema\Blueprint;  
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration  
{
  public function up()
  {
    Schema::create('users', function (Blueprint $table) {
      $table->increments('id');
      $table->string('name');
      $table->string('username')->unique()->nullable();
      $table->string('email')->unique();
      $table->string('password', 60);
      $table->boolean('is_admin');
      $table->rememberToken();
      $table->timestamps();
    });
  }

  public function down()
  {
    Schema::drop('users');
  }
}

Now we can create the middleware (it will be located under app\Http\Middleware). You can create it manually, or use php artisan make:middleware Admin, then make your changes:

<?php

namespace App\Http\Middleware;

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

class Admin  
{
  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');
      }
    } else if (!Auth::guard($guard)->user()->is_admin) {
      return redirect()->to('/')->withError('Permission Denied');
    }

    return $next($request);
  }
}

(I called it Admin, but you can be more creative :D).

Don't forget to add your middleware in the app\Kernel.php. We will create a middleware group, named "admin":

<?php

namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel  
{
  protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
  ];

  protected $middlewareGroups = [
    'web' => [
      \App\Http\Middleware\EncryptCookies::class,
      \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
      \Illuminate\Session\Middleware\StartSession::class,
      \Illuminate\View\Middleware\ShareErrorsFromSession::class,
      \App\Http\Middleware\VerifyCsrfToken::class,
    ],

    'admin' => [
      \App\Http\Middleware\EncryptCookies::class,
      \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
      \Illuminate\Session\Middleware\StartSession::class,
      \Illuminate\View\Middleware\ShareErrorsFromSession::class,
      \App\Http\Middleware\VerifyCsrfToken::class,
      \App\Http\Middleware\Admin::class,
    ],

    'api' => [
      \App\Http\Middleware\AllowOrigin::class,
      // 'throttle:60,1',
    ],
  ];

  protected $routeMiddleware = [
    'auth'       => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'guest'      => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle'   => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'cors'       => \App\Http\Middleware\AllowOrigin::class,
    'adminRole'  => \App\Http\Middleware\Admin::class,
  ];
}

The last step is to assign the middleware to the admin route(s). I will give you an example:

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