Ad Clicks : Ad Views : Ad Clicks : Ad Views : Ad Clicks : Ad Views : Ad Clicks : Ad Views : Ad Clicks : Ad Views : Ad Clicks : Ad Views : Ad Clicks : Ad Views :
InvestmentNovel

Latest Programming Tutorial Blog

How to create roles and permissions in laravel from scratch

/
/
/
277 Views

In this example, I will explain to How to create roles and permissions in laravel from scratch.  Here we build user management system with roles and permission. You can control the access of user display different UI for the different user.

How to create roles and permissions in laravel from scratch

We are going to Configure Laravel Project.

#1: Download Laravel Project

Establish  Laravel Project by the typing following command.

composer create-project --prefer-dist laravel/laravel laravelacl

#2: Database Setup and Migrations

For this tutorial the database information section of the .env looks like this:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravelacl
DB_USERNAME=root
DB_PASSWORD=

First, we define authentication so type following command in cmd.

php artisan make:auth

So we can add table one by one. Type following commands in your cmd.

For permission table :

php artisan make:migration create_permissions_table --create=permissions

It will create a create_permissions_table.php  migration file.

//create_permissions_table

public function up()
    {
        Schema::create('permissions', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

For role table:

php artisan make:migration create_roles_table --create=roles

It will create a create_roles_table.php  migration file.

//create_roles_table

public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
    }

For users permissions table:

php artisan make:migration create_user_permissions_table --create=user_permissions

It will create a create_user_permissions_table.php  migration file.

//create_user_permissions_table.php

public function up()
    {
        Schema::create('user_permissions', function (Blueprint $table) {
            $table->integer('user_id')->unsigned();
            $table->integer('permission_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
            $table->primary(['user_id','permission_id']);
        });
    }

For users roles table:

php artisan make:migration create_user_roles_table --create=user_roles

It will create a create_user_roles_table.php  migration file.

//create_user_roles_table.php

public function up()
    {
        Schema::create('user_roles', function (Blueprint $table) {
            $table->integer('user_id')->unsigned();
            $table->integer('role_id')->unsigned();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
            $table->primary(['user_id','role_id']);
        });
    }

For roles permissions table:

php artisan make:migration create_role_permissions_table --create=role_permissions

It will create a create_role_permissions_table.php  migration file.

//create_role_permissions_table.php

public function up()
    {
        Schema::create('role_permissions', function (Blueprint $table) {
            $table->integer('role_id')->unsigned();
            $table->integer('permission_id')->unsigned();
            $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
            $table->foreign('permission_id')->references('id')->on('permissions')->onDelete('cascade');
            $table->primary(['role_id','permission_id']);
        });
    }

Save and run.

php artisan migrate

Next, you would find the following tables in your database.

  • migrations: This keeps track of migration process that has run
  • password_resets: Holds token information when users demand a new password
  • users: This holds the user’s data of the application
  • permissions: This holds the various permissions required in the application
  • roles: This holds the roles in our application
  • role_permission: This is a pivot table that contains relationship information between the permissions table and the role table
  • user_roles: Also a pivot table, holds relationship information between the roles and the user’s table.
  • user_permissions: Also a pivot table, holds relationship information between the user’s table and the permissions table.

#3: Build Model 

php artisan make:model Role

It will create a Role.php file.

php artisan make:model Permission

It will create a Permission.php file.

Users have permission and roles. So let’s focus on permission. Add following code in Permission.php file.

//Permission.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Permission extends Model
{
    public function roles()
    {
        return $this->belongsToMany(Role::class , 'role_permissions');
    }
}

Now we can reverse because roles have multiple permissions. So add following code in Role.php file.

//Role.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model
{
    public function permissions()
    {
        return $this->belongsToMany(Permission::class , 'role_permissions');
    }
}

Regarding users have many roles, users have many permissions, roles have many users, permission has may users, and role has many users. Next, we can add two functions in User.php file. Add following code User.php file.

//User.php

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Role;
use App\Permission;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * 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 roles()
    {
        return $this->belongsToMany(Role::class,'user_roles');
    }

    public function permissions()
    {
        return $this->belongsToMany(Permission::class,'user_permissions');
    }
}

Here we define two methods likes roles() and permissions().  We represent many to many relationships because users have many roles and users have many permissions.

#4: Check User Role

Based on user we can check that if a user has a particular role so add following code in User.php file.

//User.php

public function hasRole(...$roles)
    {
       // dd($roles);

        foreach($roles as $role)
        {
            if($this->roles->contains('name',$role))
            {
                return true;
            }
        }
        return false;
    }

Add following code in the web.php  file.

web.php

Route::get('/', function (\Illuminate\Http\Request $request) {
    $user = $request->user();
    dd($user->hasRole('User'));
});

Here we define user role as a User. You can also define admin as per your requirement. In hasRole() method if user role match with the established role then returns true otherwise false. First, you can register yourself. In this example we add record manually you can see in below screenshot.

Roles table:

laravel roles and permission example

user_roles table:

laravel roles and permission tutorial

You can see that we define a user as a role. In roles table, User id is 1 and in the user_roles table, role_id is 1 it means when you can run the application in http://localhost:8000/ it returns true.

#5: Check User Permission

Based on user we can check that if a user has a particular permission to do something so add following code in User.php file.

//User.php

public function hasPermission($permission)
    {
        return  (bool) $this->permissions->where('name',$permission->name)->count();
    }

Add following code in the web.php  file.

//web.php

Route::get('/', function (\Illuminate\Http\Request $request) {
    $user = $request->user();
    dd($user->can('delete'));
});

Here we check user to have specific permission, also use laravel can method it work with laravel authorization. Also, we can add permission manually so check below screenshot.

Permissions table:

laravel 5 roles and permission example

user_permissions table:

laravel 5 roles and permission tutorial

Next, we can add Permission service provider so fire below command in terminal.

php artisan make:provider PermissionServiceProvider

Add service provide in config/app.php file.

'providers' => [
                 App\Providers\PermissionServiceProvider::class,
               ]

Add following code in Providers/PermissionServiceProvider.php file.

//PermissionServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Permission;
use Gate;

class PermissionServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        Permission::get()->map(function ($permission){
            Gate::define($permission->name,function($user) use ($permission)
            {
                    return $user->hasPermission($permission);
            });
        });
    }

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Everytime service provider calls and check specific user has specific permission if it is true it means the user has permission otherwise return false.

#6: Check Permission Through Roles

Now, we check permission through roles so first manually add data into the role_permission table.laravel 5.6 roles and permission example

It means user role as a User and permission as a Delete.

Add following code in User.php file.

//User.php

public function hasPermissionThroughRole($permission)
    {
        foreach($permission->roles as $role)
        {
            if($this->roles->contains($role))
            {
                return true;
            }
        }
        return false;
    }

Add hasPermissionThroughRole() method in hasPermission() function.

//User.php

public function hasPermission($permission)
    {
        return $this->hasPermissionThroughRole($permission) || (bool) $this->permissions->where('name',$permission->name)->count();
    }

Add following code in the web.php file.

//web.php

Route::get('/', function (\Illuminate\Http\Request $request) {
    $user = $request->user();
    dd($user->can('edit'));
});

If you check user have edit permission, then it will return false because we define user permission as a delete.

#7: Modify Permission

In this step we discuss user modify permission and delete the permission which assigns to the user.

Add following code into User.php file.

//User.php

public function givePermission(...$permission)
    {
        $permissions = $this->getPermissions(array_flatten($permission));
        if($permissions === null)
        {
            return $this;
        }  
        $this->permissions()->saveMany($permissions);
        return $this; 
    }
 public function getPermissions(array $permissions)
    {
        return Permission::whereIn('name',$permissions)->get();
    }

First get all permission which user assign if the user does not have any permission then it returns blank.

Add below code in a web.php file.

//web.php

Route::get('/', function (\Illuminate\Http\Request $request) {
    $user = $request->user();
    $user->givePermission();
});

When you run the project, then it returns blank because we do not give any permission to the user.

Next, we remove the permission so add following code in User.php file.

//User.php

public function removePermission(...$permission)
    {
        $permissions = $this->getPermissions(array_flatten($permission));
        $this->permissions()->detach($permissions);
        return $this;
    }

Here we detach the permission whatever you assign the permission to the user.

Add below code into the web.php file.

//web.php

Route::get('/', function (\Illuminate\Http\Request $request) {
    $user = $request->user();
    $user->removePermission('delete');
});

Save and run the project in http://localhost:8000/

You can see in user_permission table remove the delete the user_id and permissio_id.

laravel 5.6 roles and permission tutorial

Again we can permit the user So already we have created the method to use this method in the web.php file.

//web.php

Route::get('/', function (\Illuminate\Http\Request $request) {
    $user = $request->user();
    $user->givePermission('delete');
});

You can see in the database user_permissions table add the permission.

laravel 5.6 roles and permission

Next, we can modify the permission so add modifyPermission() method in User.php file.

//User.php


public function modifyPermission(...$permissions)
    {
        $this->permissions()->detach();
        return $this->givePermission($permissions);
    }

First, we detach all permission assign the user then give permission which we want. Add below code in the web.php file.

//web.php

Route::get('/', function (\Illuminate\Http\Request $request) {
    $user = $request->user();
    $user->modifyPermission('edit');
});

We change permission to edit. So you can see below screenshot that user_permissions table modify.

laravel 5 roles and permission

#8: Change in View File

Now we can modify view file as user permission if the user as edit permission then displays different view then other permissions. So add following code in the home.blade.php file.

//home.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Dashboard</div>

                <div class="card-body">
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif
                    @can('edit')
                        Hello You can  edit the post.
                   @endcan
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

You can see the output like below screenshot.

laravel 5 roles and permission tutorial with example

If your permission as a delete then you can see output like below screen.

laravel 5 roles and permissions example

Next, we can change the view as per user role so modify the code in the app.blade.php file.

//app.blade.php

<ul class="navbar-nav ml-auto">
                        <!-- Authentication Links -->
                        @guest
                            <li class="nav-item">
                                <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
                            </li>
                        @else
                        @if(auth()->user()->hasRole('User'))
                            <li>
                                <a href=""> User </a>
                            </li>   
                        @endif
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }} <span class="caret"></span>
                                </a>

                                <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" 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
                                    </form>
                                </div>
                            </li>
                        @endguest
                    </ul>

If login user role as a user role then you can see below screenshot.

roles and permission in laravel

If you log in as an admin, then you don’t see user link in the navigation.

At last, we have completed create roles and permissions in laravel is over.

  • Facebook
  • Twitter
  • Google+
  • Linkedin
  • Pinterest

2 Comments

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

This div height required for enabling the sticky sidebar