laravel permissions Tutorial with Example

Today, We want to share with you laravel permissions.In this post we will show you Easy roles and permissions in Laravel 5|6|7, hear for laravel roles and permissions from scratch we will give you demo and example for implement.In this post, we will learn about User Authorization in Laravel 5|6|7 with Spatie Laravel-Permission with an example.

laravel permissions

There are the Following The simple About laravel 5.6 – user roles and permissions Full Information With Example and source code.

As I will cover this Post with live Working example to develop spatie/laravel-permission documentation, so the laravel 6 roles and permissions is used for this example is following below.

Laravel authorization and positions permission management

Scaffold app

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

Setup packages

composer.json

"require": {
        ...
        "spatie/laravel-permission": "^2.1",
        "laracasts/flash": "^3.0",
        "laravelcollective/html": "^5.3.0"
    },

config/app.php

'providers' => [
    ...
    Spatie\Permission\PermissionServiceProvider::class,        
    Laracasts\Flash\FlashServiceProvider::class,        
    Collective\Html\HtmlServiceProvider::class,
    ...
],

'aliases' => [
    ...
    'Form' => Collective\Html\FormFacade::class,
    'Html' => Collective\Html\HtmlFacade::class,
]

create tables for positions and permissions.

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"

create Visitor, Position, Permission

// Create Visitor model with migration and resource controller
php artisan make:model Visitor -m -c --resource

// Create Position model and resource controller
php artisan make:model Position -c --resource

// Create Permission model and resource controller
php artisan make:model Permission -c --resource

add HasPositions trait provided by the package

use Spatie\Permission\Traits\HasPositions;

class Member extends Authenticatable
{
    use HasPositions;
    ...

database/seeds/DatabaseSeeder.php

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

                // create one member for each position
                $this->createMember($position);
            }

            $this->command->info('Positions ' . $input_positions . ' added successfully');

        } else {
            Position::firstOrCreate(['name' => 'Member']);
            $this->command->info('Added only default member position.');
        }

        // now lets seed some visitors for demo
        factory(\App\Visitor::class, 30)->create();
        $this->command->info('Some Visitors data seeded.');
        $this->command->warn('All done :)');
    }

    /**
     * Create a member with given position
     *
     * @param $position
     */
    private function createMember($position)
    {
        $member = factory(Member::class)->create();
        $member->assignPosition($position->name);

        if( $position->name == 'Admin' ) {
            $this->command->info('Here is your admin details to login:');
            $this->command->warn($member->email);
            $this->command->warn('Password is "secret"');
        }
    }

defaultPermissions in Permissions Model

public static function defaultPermissions()
{
    return [
        'view_members',
        'add_members',
        'edit_members',
        'delete_members',

        'view_positions',
        'add_positions',
        'edit_positions',
        'delete_positions',

        'view_visitors',
        'add_visitors',
        'edit_visitors',
        'delete_visitors',
    ];
}

Now run the seeder using php artisan db:seed

MemberController.php

positions' => 'required|min:1'
    ]);

    // Get the member
    $member = Member::findOrFail($id);

    // Update member
    $member->fill($request->except('positions', 'permissions', 'password'));

    // check for password change
    if($request->get('password')) {
        $member->password = bcrypt($request->get('password'));
    }

    // Handle the member positions
    $this->syncPermissions($request, $member);

    $member->save();
    flash()->success('Member has been updated.');
    return redirect()->route('members.index');
}

public function destroy($id)
{
    if ( Auth::member()->id == $id ) {
        flash()->warning('Deletion of currently logged in member is not allowed :(')->important();
        return redirect()->back();
    }

    if( Member::findOrFail($id)->delete() ) {
        flash()->success('Member has been deleted');
    } else {
        flash()->success('Member not deleted');
    }

    return redirect()->back();
}

private function syncPermissions(Request $request, $member)
{
    // Get the submitted positions
    $positions = $request->get('positions', []);
    $permissions = $request->get('permissions', []);

    // Get the positions
    $positions = Position::find($positions);

    // check for current position changes
    if( ! $member->hasAllPositions( $positions ) ) {
        // reset all direct permissions for member
        $member->permissions()->sync([]);
    } else {
        // handle permissions
        $member->syncPermissions($permissions);
    }

    $member->syncPositions($positions);
    return $member;
}

perform CRUD operation with certain permissions for the specific use

Route::group( ['middleware' => ['auth']], function() {
    Route::resource('members', 'MemberController');
    Route::resource('positions', 'PositionController');
    Route::resource('visitors', 'VisitorController');
});

Authorization

...
@can('add_members')
    
         Create
    
@endcan
...


        ....
        
        @can('edit_members', 'delete_members')
            
        @endcan
    
    @foreach($result as $item)
        
            ...
            @can('edit_members')
            
            @endcan
        
    @endforeach
    
Created AtActions
// action buttons

Authorizable Trait

namespace App;

trait Authorizable
{
    private $abilities = [
        'index' => 'view',
        'edit' => 'edit',
        'show' => 'view',
        'update' => 'edit',
        'create' => 'add',
        'store' => 'add',
        'destroy' => 'delete'
    ];

    /**
     * Override of callAction to perform the authorization before
     *
     * @param $method
     * @param $parameters
     * @return mixed
     */
    public function callAction($method, $parameters)
    {
        if( $ability = $this->getAbility($method) ) {
            $this->authorize($ability);
        }

        return parent::callAction($method, $parameters);
    }

    public function getAbility($method)
    {
        $routeName = explode('.', \Request::route()->getName());
        $action = array_get($this->getAbilities(), $method);

        return $action ? $action . '_' . $routeName[0] : null;
    }

    private function getAbilities()
    {
        return $this->abilities;
    }

    public function setAbilities($abilities)
    {
        $this->abilities = $abilities;
    }
}

trait on MemberController.

use App\Authorizable;

class MemberController extends Controller
{
    use Authorizable;
    ...

AuthorizationException Exception Handler

app/Exceptions/Handler.php

public function render($request, Exception $exception)
{
    if ($exception instanceof AuthorizationException) {
        return $this->unauthorized($request, $exception);
    }

    return parent::render($request, $exception);
}

private function unauthorized($request, Exception $exception)
{
    if ($request->expectsJson()) {
        return response()->json(['error' => $exception->getMessage()], 403);
    }

    flash()->warning($exception->getMessage());
    return redirect()->route('home');
}

Position Management

create the positions management resource controller

class PositionController extends Controller
{
    use Authorizable;

    public function index()
    {
        $positions = Position::all();
        $permissions = Permission::all();

        return view('position.index', compact('positions', 'permissions'));
    }

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

        if( Position::create($request->only('name')) ) {
            flash('Position Added');
        }

        return redirect()->back();
    }

    public function update(Request $request, $id)
    {
        if($position = Position::findOrFail($id)) {
            // admin position has everything
            if($position->name === 'Admin') {
                $position->syncPermissions(Permission::all());
                return redirect()->route('positions.index');
            }

            $permissions = $request->get('permissions', []);
            $position->syncPermissions($permissions);
            flash( $position->name . ' permissions has been updated.');
        } else {
            flash()->error( 'Position with id '. $id .' note found.');
        }

        return redirect()->route('positions.index');
    }
}

create resources/views/position/index.blade.php

@extends('layouts.app')

@section('title', 'Positions & Permissions')

@section('content')
    
    

    

Positions

@can('add_positions') New @endcan
@forelse ($positions as $position) {!! Form::model($position, ['method' => 'PUT', 'route' => ['positions.update', $position->id ], 'class' => 'm-b']) !!} @if($position->name === 'Admin') @include('shared._permissions', [ 'title' => $position->name .' Permissions', 'options' => ['disabled'] ]) @else @include('shared._permissions', [ 'title' => $position->name .' Permissions', 'model' => $position ]) @can('edit_positions') {!! Form::submit('Save', ['class' => 'btn btn-primary']) !!} @endcan @endif {!! Form::close() !!} @empty

No Positions defined, please run php artisan db:seed to seed some dummy data.

@endforelse @endsection

resources/views/shared/_permissions.blade.php

@foreach($permissions as $perm) hasPermissionTo($perm->name); } if( isset($member)) { $per_found = $member->hasDirectPermission($perm->name); } ?>
@endforeach

Permissions Management

command by running php artisan make:command AuthPermissionCommand

class AuthPermissionCommand extends Command
{
    protected $signature = 'auth:permission {name} {--R|remove}';
    ...

    public function handle()
    {
        $permissions = $this->generatePermissions();

        if( $is_remove = $this->option('remove') ) {
            if( Permission::where('name', 'LIKE', '%'. $this->getNameArgument())->delete() ) {
                $this->warn('Permissions ' . implode(', ', $permissions) . ' deleted.');
            }  else {
                $this->warn('No permissions for ' . $this->getNameArgument() .' found!');
            }

        } else {
            foreach ($permissions as $permission) {
                Permission::firstOrCreate(['name' => $permission ]);
            }

            $this->info('Permissions ' . implode(', ', $permissions) . ' created.');
        }

        if( $position = Position::where('name', 'Admin')->first() ) {
            $position->syncPermissions(Permission::all());
            $this->info('Admin permissions');
        }
    }

    private function generatePermissions()
    {
        $abilities = ['view', 'add', 'edit', 'delete'];
        $name = $this->getNameArgument();

        return array_map(function($val) use ($name) {
            return $val . '_'. $name;
        }, $abilities);
    }
    
    private function getNameArgument()
    {
        return strtolower(str_plural($this->argument('name')));
    }
}

app/Console/Kernel.php

App\Console\Commands\AuthPermissionCommand;

class Kernel extends ConsoleKernel
{
    protected $commands = [
        AuthPermissionCommand::class
    ];
    ...

The auth:permission command is ready, now you can run it to add/remove permissions.If you added some permissions manually in the Database, don’t forget to run/execute php artisan cache:forget spatie.permission.cache, otherwise new permissions wont work.

Web Programming Tutorials Example with Demo

Read :

Summary

You can also read about AngularJS, ASP.NET, VueJs, PHP.

I hope you get an idea about laravel 6 roles and permissions.
I would like to have feedback on my infinityknow.com blog.
Your valuable feedback, question, or comments about this article are always welcome.
If you enjoyed and liked this post, don’t forget to share.

Leave a Comment