Laravel 5.4 Users Authorization With Spatie Laravel-Permission

Laravel 5.4 Users Authorization With Spatie Laravel-Permission

In this post we will give you information about Laravel 5.4 Users Authorization With Spatie Laravel-Permission. Hear we will give you detail about Laravel 5.4 Users Authorization With Spatie Laravel-PermissionAnd how to use it also give you demo for it if it is necessary.

Today, Laravelcode share with you a very helfull tutorials related laravel role base permission system, we are share with you Laravel 5.4 Usesr Authorization With Spatie Laravel-Permission.

When you are craete any big lavel laravel application you must be needed set up user access control list (ACL) functionality for manage user role and permission for some perticuler right and athority. you manage all enty user managemant system base on role and permission which user can access which type functionality in your application. for example you ecreate one blog system and you want to give some perticuler permission to some perticuler user like some user only create blog post, some user only show blog post and they will be not to able to create blog post and not also delete any blog post. this is basic stuff for user access controll list(ACL) functionality.

Here, we are share with you how to create user access control list(ACL) functionality with laravel application using Spatie Laravel-Permission laravel package

We are apply access control list(ACL) on post article in this tutorials.

We are share here all code step by step so, please follow this step for crating laravel access control list(ACL) role permission step by step.

First we are starting look somethis it’s method and how is work


givePermissionTo(): Allows us to give persmission to a user or role
revokePermissionTo(): Revoke permission from a user or role
hasPermissionTo(): Check if a user or role has a given permission
assignRole(): Assigns role to a user
removeRole(): Removes role from a user
hasRole(): Checks if a user has a role
hasAnyRole(Role::all()): Checks if a user has any of a given list of roles
hasAllRoles(Role::all()): Checks if a user has all of a given list of role

Step : 1 Install Required Packages

We are first need to install Spatie Laravel-Permission package. please run following comand for install this package in your laravel application.


composer require spatie/laravel-permission

Step : 2 Configure Packages

Now open your confige/app.php file and add package service provider into providers array like that


'providers' => [
    ...
    SpatiePermissionPermissionServiceProvider::class,
];

Now, we need to public or create this package’s bydefault migration file by run following command :


php artisan vendor:publish --provider="SpatiePermissionPermissionServiceProvider" --tag="migrations"

Then after done this this proccess run migration by followign command :


php artisan migrate

Now, open your database and look into that their followign table created :

  • permissions : In this table we are store varius of permission
  • roles : In this table we are store user role
  • role_has_permission : This is one type of pivot table for relationship between permissions and roles table
  • model_has_roles : This also pivot table for relationship between roles and users table
  • model_has_permissions : This also pivot table for relationship between users and permissions table

Okay, now we are public configuration file by run following command :


php artisan vendor:publish --provider="SpatiePermissionPermissionServiceProvider" --tag="config"

Step : 3 Make changes in views/layout/app.blade.php file

Now, open your views/layout/app.blade.php file and here you make some changes like that simple put following all code in your file.


<!DOCTYPE html>
<html lang="{{ config('app.locale') }}">
<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 id="token" name="csrf-token" value="{{ csrf_token() }}">
    <title>{{ config('app.name', 'Laravel') }}</title>
    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    <script>
    window.csrf = "{{ csrf_token() }}";
    </script>
</head>
<body>
    <div id="">
        <nav >
            <div >
                <div >

                    <!-- Collapsed Hamburger -->
                    <button type="button"  data-toggle="collapse" data-target="#app-navbar-collapse">
                        <span >Toggle Navigation</span>
                        <span ></span>
                        <span ></span>
                        <span ></span>
                    </button>

                    <!-- Branding Image -->
                    <a  href="{{ url('/') }}">
                        {{ config('app.name', 'Laravel') }}
                    </a>
                </div>

                <div  id="app-navbar-collapse">
                    <!-- Left Side Of Navbar -->
                    <ul >
                        <li><a href="{{ url('/') }}">Home</a></li>
                        @if (!Auth::guest())
                            <li><a href="{{ route('posts.create') }}">New Article</a></li>
                        @endif
                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul >
                        <!-- Authentication Links -->
                        @if (Auth::guest())
                            <li><a href="{{ route('login') }}">Login</a></li>
                            <li><a href="{{ route('register') }}">Register</a></li>
                        @else
                            <li >
                                <a href="#"  data-toggle="dropdown" role="button" aria-expanded="false">
                                    {{ Auth::user()->name }} <span ></span>
                                </a>

                                <ul  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(Session::has('flash_message'))
            <div >      
                <div ><em> {!! session('flash_message') !!}</em>
                </div>
            </div>
        @endif 

        <div >
            <div >              
                @include ('errors.list') {{-- Including error file --}}
            </div>
        </div>

        @yield('content')

    </div>
    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}"></script>
</body>
</html>

Step : 4 Create Routes

[ADDCODE]

After changes in app.blade.php file then create following route in your web.php file.


// Laravel welcome route.
Route::get('/', function () {
    return view('welcome');
});

// Laravel auth route.
Auth::routes();

Route::get('/', '[email protected]')->name('home');

// Users resource route.
Route::resource('users', 'UserController');

// Roles resource route.
Route::resource('roles', 'RoleController');

// Permissions resource route.
Route::resource('permissions', 'PermissionController');

// Post resource route.
Route::resource('posts', 'PostController');

Step : 5 Create Post Migration

Now, we are craete post migration using this command :


php artisan make:migration crate_post_tbl

Then open created post migration file from this path database/migrations and put inti it followign code.


use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;

class CreatePostTbl extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('post', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('description');
            $table->timestamps();
        });
    }
    public function down()
    {
        Schema::drop("post");
    }
}

Step : 6 Create Post Model

Now, create one post model in this path app/Post.php file and put following code into it.


namespace App;

use IlluminateDatabaseEloquentModel;

class Post extends Model
{
	public $table = 'post';

   	public $fillable = ['title','description'];
}

Step : 7 Create Post Controller

After post model created then we need to create controller in this path app/Http/Controllers/PostController.php file and put following code.


namespace AppHttpControllers;

use IlluminateHttpRequest;
use AppPost;
use Auth;
use Session;

class PostController extends Controller {

    public function __construct() 
    {
        $this->middleware(['auth', 'clearance'])->except('index', 'show');
    }

    public function index() 
    {
        $posts = Post::orderby('id', 'desc')->paginate(5);
        return view('posts.index', compact('posts'));
    }
    
    public function create() 
    {
        return view('posts.create');
    }
    
    public function store(Request $request) 
    { 
        //Validation
        $this->validate($request, [
            'title'=>'required|max:100',
            'description' =>'required',
            ]);

        $title = $request['title'];
        $body = $request['description'];

        $post = Post::create($request->only('title', 'description'));

        //Display a successful message upon save
        return redirect()->route('posts.index')
            ->with('flash_message', 'Post,
             '. $post->title.' created');
    }
    
    public function show($id) 
    {
        $post = Post::findOrFail($id);
        return view ('posts.show', compact('post'));
    }
    
    public function edit($id) 
    {
        $post = Post::findOrFail($id);
        return view('posts.edit', compact('post'));
    }
    
    public function update(Request $request, $id) 
    {
        $this->validate($request, [
            'title'=>'required|max:100',
            'description'=>'required',
        ]);

        $post = Post::findOrFail($id);
        $post->title = $request->input('title');
        $post->body = $request->input('description');
        $post->save();

        return redirect()->route('posts.show', 
            $post->id)->with('flash_message', 
            'Post, '. $post->title.' updated');
    }
    
    public function destroy($id) 
    {
        $post = Post::findOrFail($id);
        $post->delete();

        return redirect()->route('posts.index')
            ->with('flash_message',
             'Post successfully deleted');
    }
}

Step : 8 Create View Files

We are user four view file in our PostController.php file. so, we must be create all view/blade files. we are created following blade file for Post Module.


1) resourcesviewspostsindex.blade.php
2) resourcesviewspostscreate.blade.php
3) resourcesviewspostsshow.blade.php
4) resourcesviewspostsedit.blade.php

Our index.blade.php look like.


@extends('layouts.app')
@section('content')
<div >
    <div >
        <div >
            <div >
                <div ><h3>Posts</h3></div>
                <div >
                    Page {{ $posts->currentPage() }} of {{ $posts->lastPage() }}
                </div>
                @foreach ($posts as $post)
                    <div >
                        <li style="list-style-type:disc">
                            <a href="{{ route('posts.show', $post->id ) }}"><b>{{ $post->title }}</b><br>
                                <p >
                                   {{  str_limit($post->description, 100) }}
                                </p>
                            </a>
                        </li>
                    </div>
                @endforeach
            </div>
            <div >
                {!! $posts->links() !!}
            </div>
        </div>
    </div>
</div>
@endsection

Our create.blade.php look like.


@extends('layouts.app')

@section('title', '| Create New Post')

@section('content')
<div >
    <div >
    <h1>Create New Post</h1>
    <hr>
    {{ Form::open(array('route' => 'posts.store')) }}
    <div >
        {{ Form::label('title', 'Title') }}
        {{ Form::text('title', null, array('class' => 'form-control')) }}
        <br>
        {{ Form::label('body', 'Post Body') }}
        {{ Form::textarea('body', null, array('class' => 'form-control')) }}
        <br>
        {{ Form::submit('Create Post', array('class' => 'btn btn-success btn-lg btn-block')) }}
        {{ Form::close() }}
    </div>
    </div>
</div>
@endsection

Our create.blade.php look like.


@extends('layouts.app')

@section('title', '| Create New Post')

@section('content')
<div >
    <div >
    <h1>Create New Post</h1>
    <hr>
    {{ Form::open(array('route' => 'posts.store')) }}
    <div >
        {{ Form::label('title', 'Title') }}
        {{ Form::text('title', null, array('class' => 'form-control')) }}
        <br>
        {{ Form::label('description', 'Post Description') }}
        {{ Form::textarea('description', null, array('class' => 'form-control')) }}
        <br>
        {{ Form::submit('Create Post', array('class' => 'btn btn-success btn-lg btn-block')) }}
        {{ Form::close() }}
    </div>
    </div>
</div>
@endsection

Our show.blade.php look like.


@extends('layouts.app')

@section('title', '| View Post')

@section('content')
<div >
    <h1>{{ $post->title }}</h1>
    <hr>
    <p >{{ $post->description }} </p>
    <hr>
    {!! Form::open(['method' => 'DELETE', 'route' => ['posts.destroy', $post->id] ]) !!}
    <a href="{{ url()->previous() }}" >Back</a>
    @can('Edit Post')
    <a href="{{ route('posts.edit', $post->id) }}"  role="button">Edit</a>
    @endcan
    @can('Delete Post')
    {!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!}
    @endcan
    {!! Form::close() !!}
</div>
@endsection

Our edit.blade.php look like.


@extends('layouts.app')

@section('title', '| Edit Post')

@section('content')
<div >
    <div >
        <h1>Edit Post</h1>
        <hr>
        {{ Form::model($post, array('route' => array('posts.update', $post->id), 'method' => 'PUT')) }}
        <div >
        {{ Form::label('title', 'Title') }}
        {{ Form::text('title', null, array('class' => 'form-control')) }}
        <br>
        {{ Form::label('description', 'Post Description') }}
        {{ Form::textarea('description', null, array('class' => 'form-control')) }}
        <br>
        {{ Form::submit('Save', array('class' => 'btn btn-primary')) }}
        {{ Form::close() }}
    </div>
    </div>
</div>
@endsection

Now, run your laraval application and once you check your post module work perfect? (Here we have not still create middleware so only working home page but you are login and try to create new post then it’s show error it’s not big problem just continue…) it’s all working okay then move anothe left step

Step : 9 Create User Controller

Now, we are create user module’s controller and all view files. we have already User.php model for user so, this is not needed for create once again. we need to some changes like that.

Just open app/User.php file and put following code into it.


namespace App;

use IlluminateNotificationsNotifiable;
use IlluminateFoundationAuthUser as Authenticatable;
use SpatiePermissionTraitsHasRoles;

class User extends Authenticatable
{
    use Notifiable;
    use HasRoles;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    public function setPasswordAttribute($password)
    {   
        $this->attributes['password'] = bcrypt($password);
    }
}

create app/Http/Controllers/UserController.php file and put into it following code.


namespace AppHttpControllers;

use IlluminateHttpRequest;
use AppUser;
use Auth;

use SpatiePermissionModelsRole;
use SpatiePermissionModelsPermission;
use Session;

class UserController extends Controller {

    public function __construct() 
    {
        $this->middleware(['auth', 'isAdmin']); //middleware 
    }
    
    public function index() 
    {
        $users = User::all(); 
        return view('users.index')->with('users', $users);
    }

    public function create() 
    {
        $roles = Role::get();
        return view('users.create', ['roles'=>$roles]);
    }

    public function store(Request $request) 
    {
        $this->validate($request, [
            'name'=>'required|max:120',
            'email'=>'required|email|unique:users',
            'password'=>'required|min:6|confirmed'
        ]);

        $user = User::create($request->only('email', 'name', 'password')); 

        $roles = $request['roles']; //Retrieving the roles field
        //Checking if a role was selected
        if (isset($roles)) {
            foreach ($roles as $role) {
                $role_r = Role::where('id', '=', $role)->firstOrFail();            
                $user->assignRole($role_r); //Assigning role to user
            }
        }        
        //Redirect to the users.index view and display message
        return redirect()->route('users.index')
            ->with('flash_message',
             'User successfully added.');
    }

    public function show($id) 
    {
        return redirect('users'); 
    }
    
    public function edit($id) 
    {
        $user = User::findOrFail($id);
        $roles = Role::get(); //Get all roles
        return view('users.edit', compact('user', 'roles')); //pass user and roles data to view
    }
    
    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->only(['name', 'email', 'password']); 
        $roles = $request['roles'];
        $user->fill($input)->save();

        if (isset($roles)) {        
            $user->roles()->sync($roles);          
        }        
        else {
            $user->roles()->detach();
        }
        return redirect()->route('users.index')
            ->with('flash_message',
             'User successfully edited.');
    }

    public function destroy($id) 
    {
        $user = User::findOrFail($id); 
        $user->delete();

        return redirect()->route('users.index')
            ->with('flash_message',
             'User successfully deleted.');
    }
}

After done created UserController.php file then create all following blade file.


1) resourcesviewsusersindex.blade.php
2) resourcesviewsuserscreate.blade.php
3) resourcesviewsusersedit.blade.php

Our inde.blade.php look like.


@extends('layouts.app')

@section('title', '| Users')

@section('content')
<div >
    <h1><i ></i> User Administration <a href="{{ route('roles.index') }}" >Roles</a>
    <a href="{{ route('permissions.index') }}" >Permissions</a></h1>
    <hr>
    <div >
        <table >
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Email</th>
                    <th>Date/Time Added</th>
                    <th>User Roles</th>
                    <th>Actions</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>{{-- Retrieve array of roles associated to a user and convert to string --}}
                    <td>
                    <a href="{{ route('users.edit', $user->id) }}"  style="margin-right: 3px;">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>
    <a href="{{ route('users.create') }}" >Add User</a>
</div>
@endsection	

Our create.blade.php look like.


@extends('layouts.app')

@section('title', '| Add User')

@section('content')
<div class='col-lg-4 col-lg-offset-4'>
    <h1><i class='fa fa-user-plus'></i> Add User</h1>
    <hr>
    {{ Form::open(array('url' => 'users')) }}
    <div >
        {{ Form::label('name', 'Name') }}
        {{ Form::text('name', '', array('class' => 'form-control')) }}
    </div>
    <div >
        {{ Form::label('email', 'Email') }}
        {{ Form::email('email', '', array('class' => 'form-control')) }}
    </div>
    <div class='form-group'>
        @foreach ($roles as $role)
            {{ Form::checkbox('roles[]',  $role->id ) }}
            {{ Form::label($role->name, ucfirst($role->name)) }}
            <br>
        @endforeach
    </div>
    <div >
        {{ Form::label('password', 'Password') }}
        <br>
        {{ Form::password('password', array('class' => 'form-control')) }}
    </div>
    <div >
        {{ Form::label('password', 'Confirm Password') }}
        <br>
        {{ Form::password('password_confirmation', array('class' => 'form-control')) }}
    </div>
    {{ Form::submit('Add', array('class' => 'btn btn-primary')) }}
    {{ Form::close() }}
</div>
@endsection	

Our edit.blade.php look like.


@extends('layouts.app')

@section('title', '| Edit User')

@section('content')
<div class='col-lg-4 col-lg-offset-4'>
    <h1><i class='fa fa-user-plus'></i> Edit {{$user->name}}</h1>
    <hr>
    {{ Form::model($user, array('route' => array('users.update', $user->id), 'method' => 'PUT')) }}
    <div >
        {{ Form::label('name', 'Name') }}
        {{ Form::text('name', null, array('class' => 'form-control')) }}
    </div>
    <div >
        {{ Form::label('email', 'Email') }}
        {{ Form::email('email', null, array('class' => 'form-control')) }}
    </div>
    <h5><b>Give Role</b></h5>
    <div class='form-group'>
        @foreach ($roles as $role)
            {{ Form::checkbox('roles[]',  $role->id, $user->roles ) }}
            {{ Form::label($role->name, ucfirst($role->name)) }}
            <br>
        @endforeach
    </div>
    <div >
        {{ Form::label('password', 'Password') }}
        <br>
        {{ Form::password('password', array('class' => 'form-control')) }}
    </div>
    <div >
        {{ Form::label('password', 'Confirm Password') }}
        <br>
        {{ Form::password('password_confirmation', array('class' => 'form-control')) }}
    </div>
    {{ Form::submit('Add', array('class' => 'btn btn-primary')) }}
    {{ Form::close() }}
</div>
@endsection

Now, we are done our users module. then go nex step…

Step : 10 Create PermissionController Controller

Now, we are create our Permissions module. here we are create PermissionController and all views/blades file.

So, first create controller go this path and create app/Http/Controllers/PermissionController.php file and put following code into it.


namespace AppHttpControllers;

use IlluminateHttpRequest;
use Auth;
use SpatiePermissionModelsRole;
use SpatiePermissionModelsPermission;
use Session;

class PermissionController extends Controller {

    public function __construct() 
    {
        $this->middleware(['auth', 'isAdmin']); //middleware
    }

    public function index() 
    {
        $permissions = Permission::all();
        return view('permissions.index')->with('permissions', $permissions);
    }
    
    public function create() 
    {
        $roles = Role::get();
        return view('permissions.create')->with('roles', $roles);
    }

    public function store(Request $request) 
    {
        $this->validate($request, [
            'name'=>'required|max:40',
        ]);

        $name = $request['name'];
        $permission = new Permission();
        $permission->name = $name;

        $roles = $request['roles'];

        $permission->save();

        if (!empty($request['roles'])) { //If one or more role
            foreach ($roles as $role) {
                $r = Role::where('id', '=', $role)->firstOrFail();
                $permission = Permission::where('name', '=', $name)->first();
                $r->givePermissionTo($permission);
            }
        }

        return redirect()->route('permissions.index')
            ->with('flash_message',
             'Permission'. $permission->name.' added!');
    }

    public function show($id) 
    {
        return redirect('permissions');
    }

    public function edit($id) 
    {
        $permission = Permission::findOrFail($id);
        return view('permissions.edit', compact('permission'));
    }

    public function update(Request $request, $id) 
    {
        $permission = Permission::findOrFail($id);
        $this->validate($request, [
            'name'=>'required|max:40',
        ]);
        $input = $request->all();
        $permission->fill($input)->save();

        return redirect()->route('permissions.index')
            ->with('flash_message',
             'Permission'. $permission->name.' updated!');
    }

    public function destroy($id) 
    {
        $permission = Permission::findOrFail($id);

        if ($permission->name == "Administer roles & permissions") {
            return redirect()->route('permissions.index')
            ->with('flash_message',
             'Cannot delete this Permission!');
        }

        $permission->delete();

        return redirect()->route('permissions.index')
            ->with('flash_message',
             'Permission deleted!');
    }
}

After done created controller then we are followign three view needed :


1) resourcesviewspermissionsindex.blade.php
2) resourcesviewspermissionscreate.blade.php
3) resourcesviewspermissionsedit.blade.php

Our index.blade.php look like.


@extends('layouts.app')

@section('title', '| Permissions')

@section('content')
<div >
    <h1><i ></i>Available Permissions
    <a href="{{ route('users.index') }}" >Users</a>
    <a href="{{ route('roles.index') }}" >Roles</a></h1>
    <div >
        <table >
            <thead>
                <tr>
                    <th>Permissions</th>
                    <th>Operation</th>
                </tr>
            </thead>
            <tbody>
                @foreach ($permissions as $permission)
                <tr>
                    <td>{{ $permission->name }}</td> 
                    <td>
                    <a href="{{ URL::to('permissions/'.$permission->id.'/edit') }}"  style="margin-right: 3px;">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>
    <a href="{{ URL::to('permissions/create') }}" >Add Permission</a>
</div>
@endsection

Our create.blade.php look like.


@extends('layouts.app')

@section('title', '| Create Permission')

@section('content')
<div class='col-lg-4 col-lg-offset-4'>
    <h1><i class='fa fa-key'></i> Add Permission</h1>
    <br>
    {{ Form::open(array('url' => 'permissions')) }}
    <div >
        {{ Form::label('name', 'Name') }}
        {{ Form::text('name', '', array('class' => 'form-control')) }}
    </div><br>
    @if(!$roles->isEmpty()) //If no roles exist yet
        <h4>Assign Permission to Roles</h4>
        @foreach ($roles as $role) 
            {{ Form::checkbox('roles[]',  $role->id ) }}
            {{ Form::label($role->name, ucfirst($role->name)) }}
            <br>
        @endforeach
    @endif
    <br>
    {{ Form::submit('Add', array('class' => 'btn btn-primary')) }}
    {{ Form::close() }}
</div>
@endsection

Our edit.blade.php look like.


@extends('layouts.app')

@section('title', '| Edit Permission')

@section('content')
<div class='col-lg-4 col-lg-offset-4'>
    <h1><i class='fa fa-key'></i> Edit {{$permission->name}}</h1>
    <br>
    {{ Form::model($permission, array('route' => array('permissions.update', $permission->id), 'method' => 'PUT')) }}
    <div >
        {{ Form::label('name', 'Permission Name') }}
        {{ Form::text('name', null, array('class' => 'form-control')) }}
    </div>
    <br>
    {{ Form::submit('Edit', array('class' => 'btn btn-primary')) }}
    {{ Form::close() }}
</div>
@endsection

After done Permissions module we are move our last module Roles

Step : 11 Create RoleController Controller

Now, we are create RoleController.php file and also their views file like that way.

Now create RoleController.php file in app/Http/Controllers folder and put into it following code.


namespace AppHttpControllers;

use IlluminateHttpRequest;
use Auth;
use SpatiePermissionModelsRole;
use SpatiePermissionModelsPermission;
use Session;

class RoleController extends Controller {

    public function __construct() 
    {
        $this->middleware(['auth', 'isAdmin']);//middleware 
    }

    public function index() 
    {
        $roles = Role::all();
        return view('roles.index')->with('roles', $roles);
    }

    public function create() 
    {
        $permissions = Permission::all();
        return view('roles.create', ['permissions'=>$permissions]);
    }

    public function store(Request $request) 
    {
        $this->validate($request, [
            'name'=>'required|unique:roles|max:10',
            'permissions' =>'required',
            ]
        );

        $name = $request['name'];
        $role = new Role();
        $role->name = $name;

        $permissions = $request['permissions'];

        $role->save();
        
        foreach ($permissions as $permission) {
            $p = Permission::where('id', '=', $permission)->firstOrFail(); 
            $role = Role::where('name', '=', $name)->first(); 
            $role->givePermissionTo($p);
        }

        return redirect()->route('roles.index')
            ->with('flash_message',
             'Role'. $role->name.' added!'); 
    }

    public function show($id) 
    {
        return redirect('roles');
    }

    public function edit($id) 
    {
        $role = Role::findOrFail($id);
        $permissions = Permission::all();

        return view('roles.edit', compact('role', 'permissions'));
    }

    public function update(Request $request, $id) 
    {

        $role = Role::findOrFail($id);
        
        $this->validate($request, [
            'name'=>'required|max:10|unique:roles,name,'.$id,
            'permissions' =>'required',
        ]);

        $input = $request->except(['permissions']);
        $permissions = $request['permissions'];
        $role->fill($input)->save();

        $p_all = Permission::all();

        foreach ($p_all as $p) {
            $role->revokePermissionTo($p);
        }

        foreach ($permissions as $permission) {
            $p = Permission::where('id', '=', $permission)->firstOrFail();
            $role->givePermissionTo($p);
        }

        return redirect()->route('roles.index')
            ->with('flash_message',
             'Role'. $role->name.' updated!');
    }

    public function destroy($id)
    {
        $role = Role::findOrFail($id);
        $role->delete();

        return redirect()->route('roles.index')
            ->with('flash_message',
             'Role deleted!');
    }
}

After create RoleController then create following three views/blades file.


1) resourcesviewsrolesindex.blade.php
2) resourcesviewsrolescreate.blade.php
3) resourcesviewsrolesedit.blade.php

Our index.blade.php look like.


@extends('layouts.app')

@section('title', '| Roles')

@section('content')
<div >
    <h1><i ></i> Roles
    <a href="{{ route('users.index') }}" >Users</a>
    <a href="{{ route('permissions.index') }}" >Permissions</a></h1>
    <hr>
    <div >
        <table >
            <thead>
                <tr>
                    <th>Role</th>
                    <th>Permissions</th>
                    <th>Operation</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') }}"  style="margin-right: 3px;">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>
    <a href="{{ URL::to('roles/create') }}" >Add Role</a>
</div>
@endsection

Our create.blade.php look like.


@extends('layouts.app')

@section('title', '| Add Role')

@section('content')
<div class='col-lg-4 col-lg-offset-4'>
    <h1><i class='fa fa-key'></i> Add Role</h1>
    <hr>
    {{ Form::open(array('url' => 'roles')) }}
    <div >
        {{ 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('Add', array('class' => 'btn btn-primary')) }}
    {{ Form::close() }}
</div>
@endsection

Our edit.blade.php look like.


@extends('layouts.app')

@section('title', '| Edit Role')

@section('content')
<div class='col-lg-4 col-lg-offset-4'>
    <h1><i class='fa fa-key'></i> Edit Role: {{$role->name}}</h1>
    <hr>
    {{ Form::model($role, array('route' => array('roles.update', $role->id), 'method' => 'PUT')) }}
    <div >
        {{ Form::label('name', 'Role Name') }}
        {{ Form::text('name', null, array('class' => 'form-control')) }}
    </div>
    <h5><b>Assign Permissions</b></h5>
    @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

Okay we are done all module now just remaining two middleware one is isAdmin and secont one is ClearanceMiddleware

Step : 12 Create isAdmin Middleware

Why we are create isAdmin middleware? this middleware is check user’s To restrict access to the roles and permissions page,

Create AdminMiddleware.php file in this path app/Http/Middleware/ and put into followign code.


namespace AppHttpMiddleware;

use Closure;
use IlluminateSupportFacadesAuth;
use AppUser;

class AdminMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $user = User::all()->count();
        if (!($user == 1)) {
            if (!Auth::user()->hasPermissionTo('Administer roles & permissions')) {
                abort('401');
            }
        }

        return $next($request);
    }
}

After create AdminMiddleware.php then create second middleware.

Step : 13 Create clearance Middleware

Create ClearanceMiddleware.php file in this path app/Http/Middleware/ and put into followign code.


namespace AppHttpMiddleware;

use Closure;
use IlluminateSupportFacadesAuth;

class ClearanceMiddleware {
    /**
     * Handle an incoming request.
     *
     * @param  IlluminateHttpRequest  $request
     * @param  Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next) {        
        if (Auth::user()->hasPermissionTo('Administer roles & permissions')) {
            return $next($request);
        }

        if ($request->is('posts/create')) {
            if (!Auth::user()->hasPermissionTo('Create Post')) {
                abort('401');
            } else {
                return $next($request);
            }
        }

        if ($request->is('posts/*/edit')) {
            if (!Auth::user()->hasPermissionTo('Edit Post')) {
                abort('401');
            } else {
                return $next($request);
            }
        }

        if ($request->isMethod('Delete')) {
            if (!Auth::user()->hasPermissionTo('Delete Post')) {
                abort('401');
            } else {
                return $next($request);
            }
        }

        return $next($request);
    }
}

Step : 14 Add Middleware in kernel.php File

After done both of middleware then we must be needed add both of middleware into kernel.php file like that

Open /app/Http/kernel.php file and add following two line in bottom


protected $routeMiddleware = [
    ......
    ......
    'isAdmin' => AppHttpMiddlewareAdminMiddleware::class,
    'clearance' => AppHttpMiddlewareClearanceMiddleware::class,
];

Step : 15 Create 401 page

In both of middleware when condition is false then they redirect to 401. so, we are create one static page for handle this 401 error

Create one 401.blade.php file in this path resourcesviewserrors and put into follwowing simple html code.


@extends('layouts.app')

@section('content')
<div class='col-lg-4 col-lg-offset-4'>
    <h1><center>401<br>
    ACCESS DENIED</center></h1>
</div>
@endsection

Now, we are done all things so please add some dummy role and permisssion the open following url in your browser.


http://localhost:8000/permissions

Step : 15 Create Seeder for dummy data.

If you don’t know how to added manualy records for permissions and role table then create one seed file, just open database/seeds/DatabaseSeeder.php file and put like that code for insert some dummy permissions records and also create admin user.


use IlluminateDatabaseSeeder;
use SpatiePermissionModelsPermission;
use SpatiePermissionModelsRole;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // Ask for db migration refresh, default is no
        if ($this->command->confirm('Do you wish to refresh migration before seeding, it will clear all old data ?')) {
            // Call the php artisan migrate:refresh
            $this->command->call('migrate:refresh');
            $this->command->warn("Data cleared, starting from blank database.");
        }

        // Seed the default permissions
        Permission::firstOrCreate(['name' => 'Administer roles & permissions', 'guard_name' => 'isAdmin']);
        

        $this->command->info('Default Permissions added.');

        // Confirm roles needed
        if ($this->command->confirm('Create Roles for user, default is admin and user? [y|N]', true)) {

            // Ask for roles from input
            $input_roles = $this->command->ask('Enter roles in comma separate format.', 'Admin,User');

            // Explode roles
            $roles_array = explode(',', $input_roles);

            // add roles
            foreach($roles_array as $role) {
                $role = Role::firstOrCreate(['name' => trim($role), 'guard_name' => 'isAdmin']);

                if( $role->name == 'Admin' ) {
                    // assign all permissions
                    $role->syncPermissions(Permission::all());
                    $this->command->info('Admin granted all the permissions');
                } else {
                    // for others by default only read access
                    $role->syncPermissions(Permission::where('name', 'LIKE', 'view_%')->get());
                }

                // create one user for each role
                $this->createUser($role);
            }

            $this->command->info('Roles ' . $input_roles . ' added successfully');

        } else {
            Role::firstOrCreate(['name' => 'User']);
            $this->command->info('Added only default user role.');
        }

        // now lets seed some posts for demo
        $this->command->info('Some Posts data seeded.');
        $this->command->warn('All done :)');
    }

    /**
     * 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('Here is your admin details to login:');
            $this->command->warn($user->email);
            $this->command->warn('Password is "secret"');
        }
    }
}

Now we are ready to run our example so run bellow command ro quick run:


php artisan serve

Now you can open bellow URL on your browser:


http://localhost:8000/permissions

If you face any problem then please write a comment or give some suggestions for improvement. Thanks…

Hope this code and post will helped you for implement Laravel 5.4 Users Authorization With Spatie Laravel-Permission. if you need any help or any feedback give it in comment section or you have good idea about this post you can give it comment section. Your comment will help us for help you more and improve us. we will give you this type of more interesting post in featured also so, For more interesting post and code Keep reading our blogs

For More Info See :: laravel And github

We're accepting well-written guest posts and this is a great opportunity to collaborate : Contact US