In this Laravel tutorial, I will tell you how to implement role and permission (ACL) to a user in the Laravel application.
For example, A user may have permission to change anything but other user may have permission to read only within the application.
In this example, I will create a simple blog application with role and permission that means you can give access to user to edit post, create post, delete post etc.
I will define role and permission on database level that will manage by a UI in the admin panel.
There are so many package built in Laravel to implement role and permission but for this example I am going to use spatie/laravel-permission
package.
By the end of this tutorial, you will be able to define rights for authenticated users using role and permissions.
Install Laravel 5.5 and Configure the permission packageFirst, We will install fresh Laravel application by running following composer command :
composer create-project --prefer-dist laravel/laravel blog
After successfully installation, create the database and update database credential in .env
file.
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=blog DB_USERNAME=root DB_PASSWORD=
Now install the Laravel permission package :
composer require spatie/laravel-permission
Now add the provider in the list of service provider, Open config/app.php
file and add Spatie\Permission\PermissionServiceProvider::class.
'providers' => [ ... Spatie\Permission\PermissionServiceProvider::class, ];
Now run the artisan command to publish migration file :
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
To create table from migration file, run following artisan command :
php artisan migrate
If you are running lower version of MySQL then you may get following error :
[Illuminate\Database\QueryException] SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email)) [PDOException] SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
To avoid this error, edit the app\Providers\AppServiceProvider.php
file :
use Illuminate\Support\Facades\Schema; public function boot() { Schema::defaultStringLength(191); }
Now you can run migrate command again to create table into database.
Laravel Collective HTML Form builderNow install the Laravel Collective HTML Form builder to avoid the error "Class Form not found".
And then add provider to providers array
'providers' => [ ... Collective\Html\HtmlServiceProvider::class, ];
Next add the aliases to aliases array :
'aliases' => [ ... 'Form' => Collective\Html\FormFacade::class, 'Html' => Collective\Html\HtmlFacade::class, ],
With the fresh installation of Laravel, You will have User
model by default.
Now I need to create Role, Permission and Post models with their resource controller.
Spatie\Permission already have role and permissions model, you just need to publish them but I will create manually Model and Controller class by running following command :
// Create Role model and resource controller php artisan make:model Role -c --resource // Create Permission model and resource controller php artisan make:model Permission -c --resource // Create Post model with migration and resource controller php artisan make:model Post -m -c --resource
By default Role and Permission class will extend default Model
class :
- class Role extends Model { }
You need to edit Role and Permission class to extend \Spatie\Permission\Models\
.
- // Permission Model
- class Permission extends \Spatie\Permission\Models\Permission { }
- // Role Model
- class Role extends \Spatie\Permission\Models\Role { }
When you run php artisan make:model Post -m -c --resource
command then you will have migration file to create post table, So edit you migration file :
- Schema::create('posts', function (Blueprint $table) {
- $table->increments('id');
- $table->string('title');
- $table->text('body');
- $table->timestamps();
- });
Run migrate command to create post table again.
Next we need to add HasRoles
trait to User model.
- use Spatie\Permission\Traits\HasRoles;
- class User extends Authenticatable {
- use HasRoles;
- ...
- }
Next we will add some default permission in Permission Model :
- <?php
- namespace App;
- use Illuminate\Database\Eloquent\Model;
- class Permission extends \Spatie\Permission\Models\Permission
- {
- public static function defaultPermissions()
- {
- return [
- 'viewPost',
- 'addPost',
- 'editPost',
- 'deletePost',
- ];
- }
- }
Now we will use Database seeder to seed data for testing our app.
database/seeds/DatabaseSeeder.php
- <?php
- use Illuminate\Database\Seeder;
- use App\Permission;
- use App\Role;
- use App\User;
- use App\Post;
- class DatabaseSeeder extends Seeder
- {
- /**
- * Run the database seeds.
- *
- * @return void
- */
- public function run()
- {
- // Ask for confirmation to refresh migration
- if ($this->command->confirm('Do you wish to refresh migration before seeding, Make sure it will clear all old data ?')) {
- $this->command->call('migrate:refresh');
- $this->command->warn("Data deleted, starting from fresh database.");
- }
- // Seed the default permissions
- $permissions = Permission::defaultPermissions();
- foreach ($permissions as $permission) {
- Permission::firstOrCreate(['name' => $permission]);
- }
- $this->command->info('Default Permissions added.');
- // Ask to confirm to assign admin or user role
- if ($this->command->confirm('Create Roles for user, default is admin and user? [y|N]', true)) {
- // Ask for roles from input
- $roles = $this->command->ask('Enter roles in comma separate format.', 'Admin,User');
- // Explode roles
- $rolesArray = explode(',', $roles);
- // add roles
- foreach($rolesArray as $role) {
- $role = Role::firstOrCreate(['name' => trim($role)]);
- if( $role->name == 'Admin' ) {
- // assign all permissions to admin role
- $role->permissions()->sync(Permission::all());
- $this->command->info('Admin will have full rights');
- } else {
- // for others, give access to view only
- $role->permissions()->sync(Permission::where('name', 'LIKE', 'view_%')->get());
- }
- // create one user for each role
- $this->createUser($role);
- }
- $this->command->info('Roles ' . $roles . ' added successfully');
- } else {
- Role::firstOrCreate(['name' => 'User']);
- $this->command->info('By default, User role added.');
- }
- }
- /**
- * Create a user with given role
- *
- * @param $role
- */
- private function createUser($role)
- {
- $user = factory(User::class)->create();
- $user->assignRole($role->name);
- if( $role->name == 'Admin' ) {
- $this->command->info('Admin login details:');
- $this->command->warn('Username : '.$user->email);
- $this->command->warn('Password : "secret"');
- }
- }
- }
Next run the seeder using following command :
php artisan db:seed
Ok, Everything is setup now.
Next we will perform simple CRUD operation on "Role", "Permission", "User" and "Post" module.
Register routesNow add following routes in your routes/web.php
:
Route::group( ['middleware' => ['auth']], function() { Route::resource('users', 'UserController'); Route::resource('roles', 'RoleController'); Route::resource('posts', 'PostController'); Route::resource('permissions','PermissionController'); });Master Layout 'resources/views/layouts/app.blade.php'
- <!DOCTYPE html>
- <html lang="{{ app()->getLocale() }}">
- <head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <!-- CSRF Token -->
- <meta name="csrf-token" content="{{ csrf_token() }}">
- <title>{{ config('app.name', 'Laravel') }}</title>
- <!-- Styles -->
- <link href="{{ asset('css/app.css') }}" rel="stylesheet">
- </head>
- <body>
- <div id="app">
- <nav class="navbar navbar-default navbar-static-top">
- <div class="container">
- <div class="navbar-header">
- <!-- Collapsed Hamburger -->
- <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
- <span class="sr-only">Toggle Navigation</span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <!-- Branding Image -->
- <a class="navbar-brand" href="{{ url('/') }}">
- {{ config('app.name', 'Laravel') }}
- </a>
- </div>
- <div class="collapse navbar-collapse" id="app-navbar-collapse">
- <!-- Left Side Of Navbar -->
- <ul class="nav navbar-nav">
-
- </ul>
- <!-- Right Side Of Navbar -->
- <ul class="nav navbar-nav navbar-right">
- <!-- Authentication Links -->
- @if (Auth::guest())
- <li><a href="{{ route('login') }}">Login</a></li>
- <li><a href="{{ route('register') }}">Register</a></li>
- @else
- <li class="dropdown">
- <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
- {{ Auth::user()->name }} <span class="caret"></span>
- </a>
- <ul class="dropdown-menu" role="menu">
- <li>
- <a href="{{ route('logout') }}"
- onclick="event.preventDefault();
- document.getElementById('logout-form').submit();">
- Logout
- </a>
- <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
- {{ csrf_field() }}
- </form>
- </li>
- </ul>
- </li>
- @endif
- </ul>
- </div>
- </div>
- </nav>
- @if ($message = Session::get('success'))
- <div class="alert alert-success">
- <p>{{ $message }}</p>
- </div>
- @endif
- @yield('content')
- </div>
- <!-- Scripts -->
- <script src="{{ asset('js/app.js') }}"></script>
- </body>
- </html>
Now add following code in UserController.php
:
- <?php
- namespace App\Http\Controllers;
- use Illuminate\Http\Request;
- use App\User;
- use App\Role;
- use App\Permission;
- class UserController extends Controller
- {
- /**
- * Create a new controller instance.
- *
- * @return void
- */
- public function __construct()
- {
- $this->middleware('auth');
- }
- /**
- * Show the application dashboard.
- *
- * @return \Illuminate\Http\Response
- */
- public function index()
- {
- $users = User::latest()->paginate();
- return view('users.index', compact('users'));
- }
- public function create()
- {
- $roles = Role::get();
- return view('users.create', compact('roles'));
- }
- public function store(Request $request)
- {
- $this->validate($request, [
- 'name' => 'required',
- 'email' => 'required|email|unique:users',
- 'password' => 'required|min:6|confirmed',
- 'roles' => 'required'
- ]);
- $user = User::create($request->except('roles'));
- if($request->roles <> ''){
- $user->roles()->attach($request->roles);
- }
- return redirect()->route('users.index')->with('success','User has been created');
- }
- public function edit($id) {
- $user = User::findOrFail($id);
- $roles = Role::get();
- return view('users.edit', compact('user', 'roles'));
- }
- public function update(Request $request, $id) {
- $user = User::findOrFail($id);
- $this->validate($request, [
- 'name'=>'required|max:120',
- 'email'=>'required|email|unique:users,email,'.$id,
- 'password'=>'required|min:6|confirmed'
- ]);
- $input = $request->except('roles');
- $user->fill($input)->save();
- if ($request->roles <> '') {
- $user->roles()->sync($request->roles);
- }
- else {
- $user->roles()->detach();
- }
- return redirect()->route('users.index')->with('success',
- 'User successfully updated.');
- }
- public function destroy($id) {
- $user = User::findOrFail($id);
- $user->delete();
- return redirect()->route('users.index')->with('success',
- 'User successfully deleted.');
- }
- }
In store()
method, A new user is registered with selected roles.
In update()
method, I will update the user details and update roles with sync
method.
Use mutator in app\User.php
file that will encrypt password while registering new user.
- public function setPasswordAttribute($password)
- {
- $this->attributes['password'] = bcrypt($password);
- }
There are three views required :
index.blade.phpThis file will contain a HTML Table with list of all users.
- {{-- \resources\views\users\index.blade.php --}}
- @extends('layouts.app')
- @section('title', '| Users')
- @section('content')
- <div class="col-lg-10 col-lg-offset-1">
- <h1><i class="fa fa-users"></i> User Management
- <a href="{{ route('roles.index') }}" class="btn btn-default pull-right">Roles</a>
- <a href="{{ route('permissions.index') }}" class="btn btn-default pull-right">Permissions</a>
- <a href="{{ route('users.create') }}" class="btn btn-success">Add User</a>
- </h1>
- <hr>
- <div class="table-responsive">
- <table class="table table-bordered table-striped">
- <thead>
- <tr>
- <th>Name</th>
- <th>Email</th>
- <th>Date/Time Added</th>
- <th>User Roles</th>
- <th>Action</th>
- </tr>
- </thead>
- <tbody>
- @foreach ($users as $user)
- <tr>
- <td>{{ $user->name }}</td>
- <td>{{ $user->email }}</td>
- <td>{{ $user->created_at->format('F d, Y h:ia') }}</td>
- <td>{{ $user->roles()->pluck('name')->implode(' ') }}</td>
- <td>
- <a href="{{ route('users.edit', $user->id) }}" class="btn btn-warning">Edit</a>
- {!! Form::open(['method' => 'DELETE', 'route' => ['users.destroy', $user->id] ]) !!}
- {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!}
- {!! Form::close() !!}
- </td>
- </tr>
- @endforeach
- </tbody>
- </table>
- </div>
- </div>
- @endsection
- {{-- \resources\views\users\create.blade.php --}}
- @extends('layouts.app')
- @section('title', '| Create User')
- @section('content')
- <div class='col-lg-4 col-lg-offset-4'>
- <h1><i class='fa fa-user-plus'></i> Create User</h1>
- <hr>
- {!! Form::open(array('url' => 'users')) !!}
- <div class="form-group @if ($errors->has('name')) has-error @endif">
- {!! Form::label('name', 'Name') !!}
- {!! Form::text('name', '', array('class' => 'form-control')) !!}
- </div>
- <div class="form-group @if ($errors->has('email')) has-error @endif">
- {!! Form::label('email', 'Email') !!}
- {!! Form::email('email', '', array('class' => 'form-control')) !!}
- </div>
- <div class="form-group @if ($errors->has('roles')) has-error @endif">
- @foreach ($roles as $role)
- {!! Form::checkbox('roles[]', $role->id ) !!}
- {!! Form::label($role->name, ucfirst($role->name)) !!}<br>
- @endforeach
- </div>
- <div class="form-group @if ($errors->has('password')) has-error @endif">
- {!! Form::label('password', 'Password') !!}<br>
- {!! Form::password('password', array('class' => 'form-control')) !!}
- </div>
- <div class="form-group @if ($errors->has('password')) has-error @endif">
- {!! Form::label('password', 'Confirm Password') !!}<br>
- {!! Form::password('password_confirmation', array('class' => 'form-control')) !!}
- </div>
- {!! Form::submit('Register', array('class' => 'btn btn-primary')) !!}
- {!! Form::close() !!}
- </div>
- @endsection
- {{-- \resources\views\users\edit.blade.php --}}
- @extends('layouts.app')
- @section('title', '| Update User')
- @section('content')
- <div class='col-lg-4 col-lg-offset-4'>
- <h1><i class='fa fa-user-plus'></i> Update {{$user->name}}</h1>
- <hr>
- {{ Form::model($user, array('route' => array('users.update', $user->id), 'method' => 'PUT')) }}
- <div class="form-group @if ($errors->has('name')) has-error @endif">
- {{ Form::label('name', 'Name') }}
- {{ Form::text('name', null, array('class' => 'form-control')) }}
- </div>
- <div class="form-group @if ($errors->has('email')) has-error @endif">
- {{ Form::label('email', 'Email') }}
- {{ Form::email('email', null, array('class' => 'form-control')) }}
- </div>
- <h5><b>Assign Role</b></h5>
- <div class="form-group @if ($errors->has('roles')) has-error @endif">
- @foreach ($roles as $role)
- {{ Form::checkbox('roles[]', $role->id, $user->roles ) }}
- {{ Form::label($role->name, ucfirst($role->name)) }}<br>
- @endforeach
- </div>
- <div class="form-group @if ($errors->has('password')) has-error @endif">
- {{ Form::label('password', 'Password') }}<br>
- {{ Form::password('password', array('class' => 'form-control')) }}
- </div>
- <div class="form-group @if ($errors->has('password')) has-error @endif">
- {{ Form::label('password', 'Confirm Password') }}<br>
- {{ Form::password('password_confirmation', array('class' => 'form-control')) }}
- </div>
- {{ Form::submit('Update', array('class' => 'btn btn-primary')) }}
- {{ Form::close() }}
- </div>
- @endsection
Now add following code in RoleController.php
to create new role.
- <?php
- namespace App\Http\Controllers;
- use App\Role;
- use App\Permission;
- use Illuminate\Http\Request;
- class RoleController extends Controller
- {
- public function __construct()
- {
- $this->middleware('auth');
- }
- public function index()
- {
- $roles = Role::all();
- return view('roles.index',compact('roles'));
- }
- /**
- * Show the form for creating a new resource.
- *
- * @return \Illuminate\Http\Response
- */
- public function create()
- {
- $permissions = Permission::all();//Get all permissions
- return view('roles.create', compact('permissions'));
- }
- /**
- * Store a newly created resource in storage.
- *
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\Http\Response
- */
- public function store(Request $request)
- {
- $this->validate($request, [
- 'name'=>'required|unique:roles|max:10',
- 'permissions' =>'required',
- ]
- );
- $role = new Role();
- $role->name = $request->name;
- $role->save();
- if($request->permissions <> ''){
- $role->permissions()->attach($request->permissions);
- }
- return redirect()->route('roles.index')->with('success','Roles added successfully');
- }
- public function edit($id) {
- $role = Role::findOrFail($id);
- $permissions = Permission::all();
- return view('roles.edit', compact('role', 'permissions'));
- }
- /**
- * Update the specified resource in storage.
- *
- * @param \Illuminate\Http\Request $request
- * @param \App\Role $role
- * @return \Illuminate\Http\Response
- */
- public function update(Request $request,$id)
- {
- $role = Role::findOrFail($id);//Get role with the given id
- //Validate name and permission fields
- $this->validate($request, [
- 'name'=>'required|max:10|unique:roles,name,'.$id,
- 'permissions' =>'required',
- ]);
- $input = $request->except(['permissions']);
- $role->fill($input)->save();
- if($request->permissions <> ''){
- $role->permissions()->sync($request->permissions);
- }
- return redirect()->route('roles.index')->with('success','Roles updated successfully');
- }
- /**
- * Remove the specified resource from storage.
- *
- * @param \App\Role $role
- * @return \Illuminate\Http\Response
- */
- public function destroy($id)
- {
- $role = Role::findOrFail($id);
- $role->delete();
- return redirect()->route('roles.index')
- ->with('success',
- 'Role deleted successfully!');
- }
- }
- @extends('layouts.app')
- @section('title', '| Roles')
- @section('content')
- <div class="col-lg-10 col-lg-offset-1">
- <h1><i class="fa fa-key"></i> Roles Management
- <a href="{{ route('users.index') }}" class="btn btn-default pull-right">Users</a>
- <a href="{{ route('permissions.index') }}" class="btn btn-default pull-right">Permissions</a>
- <a href="{{ URL::to('roles/create') }}" class="btn btn-success">Add Role</a>
- </h1>
- <hr>
- <div class="table-responsive">
- <table class="table table-bordered table-striped">
- <thead>
- <tr>
- <th>Role</th>
- <th>Permissions</th>
- <th>Action</th>
- </tr>
- </thead>
- <tbody>
- @foreach ($roles as $role)
- <tr>
- <td>{{ $role->name }}</td>
- <td>{{ str_replace(array('[',']','"'),'', $role->permissions()->pluck('name')) }}</td>
- <td>
- <a href="{{ URL::to('roles/'.$role->id.'/edit') }}" class="btn btn-warning pull-left">Edit</a>
- {!! Form::open(['method' => 'DELETE', 'route' => ['roles.destroy', $role->id] ]) !!}
- {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!}
- {!! Form::close() !!}
- </td>
- </tr>
- @endforeach
- </tbody>
- </table>
- </div>
- </div>
- @endsection
- {{-- \resources\views\roles\create.blade.php --}}
- @extends('layouts.app')
- @section('title', '| Create Role')
- @section('content')
- <div class='col-lg-4 col-lg-offset-4'>
- <h1><i class='fa fa-key'></i> Create Role</h1>
- <hr>
- {{ Form::open(array('url' => 'roles')) }}
- <div class="form-group">
- {{ Form::label('name', 'Name') }}
- {{ Form::text('name', null, array('class' => 'form-control')) }}
- </div>
- <h5><b>Assign Permissions</b></h5>
- <div class='form-group'>
- @foreach ($permissions as $permission)
- {{ Form::checkbox('permissions[]', $permission->id ) }}
- {{ Form::label($permission->name, ucfirst($permission->name)) }}<br>
- @endforeach
- </div>
- {{ Form::submit('Save', array('class' => 'btn btn-primary')) }}
- {{ Form::close() }}
- </div>
- @endsection
- @extends('layouts.app')
- @section('title', '| Update Role')
- @section('content')
- <div class='col-md-4 col-md-offset-4'>
- <h1><i class='fa fa-key'></i> Update Role: {{$role->name}}</h1>
- <hr>
- {{ Form::model($role, array('route' => array('roles.update', $role->id), 'method' => 'PUT')) }}
- <div class="form-group">
- {{ Form::label('name', 'Role Name') }}
- {{ Form::text('name', null, array('class' => 'form-control')) }}
- </div>
- <h3>Assign Permissions</h3>
- @foreach ($permissions as $permission)
- {{Form::checkbox('permissions[]', $permission->id, $role->permissions ) }}
- {{Form::label($permission->name, ucfirst($permission->name)) }}<br>
- @endforeach
- <br>
- {{ Form::submit('Edit', array('class' => 'btn btn-primary')) }}
- {{ Form::close() }}
- </div>
- @endsection
Add following code in PermissionController.php.
- <?php
- namespace App\Http\Controllers;
- use App\Permission;
- use App\Role;
- use Illuminate\Http\Request;
- class PermissionController extends Controller
- {
- public function __construct()
- {
- $this->middleware('auth');
- }
- public function index()
- {
- $permissions = Permission::all();
- return view('permissions.index',compact('permissions'));
- }
- /**
- * Show the form for creating a new resource.
- *
- * @return \Illuminate\Http\Response
- */
- public function create()
- {
- $roles = Role::get(); //Get all roles
- return view('permissions.create',compact('roles'));
- }
- /**
- * Store a newly created resource in storage.
- *
- * @param \Illuminate\Http\Request $request
- * @return \Illuminate\Http\Response
- */
- public function store(Request $request)
- {
- $this->validate($request, [
- 'name'=>'required|max:40',
- ]);
- $permission = new Permission();
- $permission->name = $request->name;
- $permission->save();
- if ($request->roles <> '') {
- foreach ($request->roles as $key=>$value) {
- $role = Role::find($value);
- $role->permissions()->attach($permission);
- }
- }
- return redirect()->route('permissions.index')->with('success','Permission added successfully');
- }
- public function edit(Permission $permission)
- {
- return view('permissions.edit', compact('permission'));
- }
- /**
- * Update the specified resource in storage.
- *
- * @param \Illuminate\Http\Request $request
- * @param \App\Permission $permission
- * @return \Illuminate\Http\Response
- */
- public function update(Request $request, Permission $permission)
- {
- $this->validate($request, [
- 'name'=>'required',
- ]);
- $permission->name=$request->name;
- $permission->save();
- return redirect()->route('permissions.index')
- ->with('success',
- 'Permission'. $permission->name.' updated!');
- }
- /**
- * Remove the specified resource from storage.
- *
- * @param \App\Permission $permission
- * @return \Illuminate\Http\Response
- */
- public function destroy(Permission $permission)
- {
- $permission->delete();
- return redirect()->route('permissions.index')
- ->with('success',
- 'Permission deleted successfully!');
- }
- }
- {{-- \resources\views\permissions\index.blade.php --}}
- @extends('layouts.app')
- @section('title', '| Permissions')
- @section('content')
- <div class="col-md-10 col-md-offset-1">
- <h1><i class="fa fa-key"></i>Permissions Management
- <a href="{{ route('users.index') }}" class="btn btn-default pull-right">Users</a>
- <a href="{{ route('roles.index') }}" class="btn btn-default pull-right">Roles</a>
- <a href="{{ URL::to('permissions/create') }}" class="btn btn-success">Add Permission</a>
- </h1>
- <hr>
- <div class="table-responsive">
- <table class="table table-bordered table-striped">
- <thead>
- <tr>
- <th>Permissions</th>
- <th>Action</th>
- </tr>
- </thead>
- <tbody>
- @foreach ($permissions as $permission)
- <tr>
- <td>{{ $permission->name }}</td>
- <td>
- <a href="{{ URL::to('permissions/'.$permission->id.'/edit') }}" class="btn btn-warning pull-left">Edit</a>
- {!! Form::open(['method' => 'DELETE', 'route' => ['permissions.destroy', $permission->id] ]) !!}
- {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!}
- {!! Form::close() !!}
- </td>
- </tr>
- @endforeach
- </tbody>
- </table>
- </div>
- </div>
- @endsection
- @extends('layouts.app')
- @section('title', '| Create Permission')
- @section('content')
- <div class='col-md-4 col-md-offset-4'>
- <h1><i class='fa fa-key'></i> Create New Permission</h1>
- <br>
- {{ Form::open(array('url' => 'permissions')) }}
- <div class="form-group">
- {{ Form::label('name', 'Name') }}
- {{ Form::text('name', '', array('class' => 'form-control')) }}
- </div><br>
- @if(!$roles->isEmpty())
- <h3>Assign Permission to Roles</h3>
- @foreach ($roles as $role)
- {{ Form::checkbox('roles[]', $role->id ) }}
- {{ Form::label($role->name, ucfirst($role->name)) }}<br>
- @endforeach
- @endif
- <br>
- {{ Form::submit('Save', array('class' => 'btn btn-primary')) }}
- {{ Form::close() }}
- </div>
- @endsection
- @extends('layouts.app')
- @section('title', '| Update Permission')
- @section('content')
- <div class='col-md-4 col-md-offset-4'>
- <h1><i class='fa fa-key'></i> Update {{$permission->name}}</h1>
- <br>
- {{ Form::model($permission, array('route' => array('permissions.update', $permission->id), 'method' => 'PUT')) }}
- <div class="form-group">
- {{ Form::label('name', 'Permission Name') }}
- {{ Form::text('name', null, array('class' => 'form-control')) }}
- </div>
- <br>
- {{ Form::submit('Update', array('class' => 'btn btn-primary')) }}
- {{ Form::close() }}
- </div>
- @endsection
- <?php
- namespace App\Http\Controllers;
- use App\Post;
- use Illuminate\Http\Request;
- class PostController extends Controller
- {
- public function __construct()
- {
- $this->middleware('auth');
- }
- public function index()
- {
- $posts = Post::latest()->paginate(10);
- return view('posts.index', compact('posts'));
- }
- }
Now create index.blade.php file in resources\views\posts\index.blade.php.
- @extends('layouts.app')
- @section('content')
- <div class="container">
- <div class="row">
- <div class="col-md-10 col-md-offset-1">
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3>Posts Management</h3>
- </div>
- <div class="panel-body">
- <div class="table-responsive">
- <table class="table table-bordered table-striped">
- <thead>
- <tr>
- <th>Title</th>
- <th>Body</th>
- <th>Action</th>
- </tr>
- </thead>
- <tbody>
- @foreach ($posts as $post)
- <tr>
- <td>{{ $post->title }}</td>
- <td>{{ $post->body }}</td>
- <td>
- @can('editPost')
- <a href="{{ route('posts.edit', $post->id) }}" class="btn btn-info pull-left">Edit</a>
- @endcan
- @can('deletePost')
- {!! Form::open(['method' => 'DELETE', 'route' => ['posts.destroy', $post->id] ]) !!}
- {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!}
- {!! Form::close() !!}
- @endcan
- </td>
- </tr>
- @endforeach
- </tbody>
- </table>
- </div>
- </div>
- </div>
- <div class="text-center">
- {!! $posts->render() !!}
- </div>
- </div>
- </div>
- </div>
- @endsection
That's it..
You can restrict routes for "User" role using middleware.
In middleware, We will authenticate the current user if user has "Admin" role then User will have full access.
Middleware
- <?php
- namespace App\Http\Middleware;
- use Closure;
- use Illuminate\Support\Facades\Auth;
- class PermissionMiddleware {
- public function handle($request, Closure $next) {
- if (Auth::user()->hasRole('Admin')) //If user has admin role
- {
- return $next($request);
- }
- if (Auth::user()->hasRole('User')) //If user has user role
- {
- if ($request->is('posts/create'))//If user is creating a post
- {
- if (!Auth::user()->hasPermissionTo('addPost'))
- {
- abort('401');
- }
- else {
- return $next($request);
- }
- }
- }
- return $next($request);
- }
- }
Now add the PermissionMiddleware::class
to $routeMiddleware
property in app/Http/kernel.php :
- protected $routeMiddleware = [
- ....
- 'has_permission' => \App\Http\Middleware\PermissionMiddleware::class,
- ];
In middleware, I redirect to user to 401 custom error page if the user does not have rights to access routes.
401.blade.php
- {{-- \resources\views\errors\401.blade.php --}}
- @extends('layouts.app')
- @section('content')
- <div class='col-md-4 col-md-offset-4'>
- <h3><center>401<br>
- You do not have permission</center></h3>
- </div>
- @endsection
Now you can set the middleware to route group like this :
- Route::group( ['middleware' => ['auth','has_permission']], function() {
- });