Connect with us

How to use the same Guard name in WEB and API Using Laravel Spatie Permission

kizinho

Published

on

Follow
NEWS: How to use the same Guard name in WEB and API Using Laravel Spatie Permission [New  Developer] » Naijacrawl
Photo: Naijacrawl

Hi, Folks will show how to use the same guard name on your Laravel application using Laravel Spatie Permission without creating multiple guards for your web and API when building your real projects.


Spatie Permission comes with guard name it is used to authenticate user role and permission in your laravel app. But what if you have Role and Permission with Guard Name Web, it means only web can use this permission or role, when you want to use it for API to Authorize user Permission or Role, this would not work and you will always get user don't have permission to access this page.


In this article, you can now use a single Guard name for both Web and API.


Guard name depends on your application usage, guard name can be admin,user, but i prefer to use guard name as web or API, so that i don't have to create each role and permission for different guard name, and it saves time to use single guard name in all your applications. So let's start


Go to this file vendor/spatie/laravel-permission/src/Models/Role and add protected $guard_name = 'web' .

You can change the $guard_name to whatever you want to use as your guard name.


See Full Code

namespace Spatie\Permission\Models;


use Spatie\Permission\Guard;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\Traits\HasPermissions;
use Spatie\Permission\Exceptions\RoleDoesNotExist;
use Spatie\Permission\Exceptions\GuardDoesNotMatch;
use Spatie\Permission\Exceptions\RoleAlreadyExists;
use Spatie\Permission\Contracts\Role as RoleContract;
use Spatie\Permission\Traits\RefreshesPermissionCache;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;


class Role extends Model implements RoleContract {


    use HasPermissions;
    use RefreshesPermissionCache;


    protected $guarded = ['id'];
    protected $guard_name = 'web';


    public function __construct(array $attributes = []) {
        $attributes['guard_name'] = $attributes['guard_name'] ?? config('auth.defaults.guard');


        parent::__construct($attributes);


        $this->setTable(config('permission.table_names.roles'));
    }


    public static function create(array $attributes = []) {
        $attributes['guard_name'] = $attributes['guard_name'] ?? Guard::getDefaultName(static::class);


        if (static::where('name', $attributes['name'])->where('guard_name', $attributes['guard_name'])->first()) {
            throw RoleAlreadyExists::create($attributes['name'], $attributes['guard_name']);
        }


        if (isNotLumen() && app()::VERSION < '5.4') {
            return parent::create($attributes);
        }


        return static::query()->create($attributes);
    }


    /**
     * A role may be given various permissions.
     */
    public function permissions(): BelongsToMany {
        return $this->belongsToMany(
                        config('permission.models.permission'), config('permission.table_names.role_has_permissions'), 'role_id', 'permission_id'
        );
    }


    /**
     * A role belongs to some users of the model associated with its guard.
     */
    public function users(): MorphToMany {
        return $this->morphedByMany(
                        getModelForGuard($this->attributes['guard_name']), 'model', config('permission.table_names.model_has_roles'), 'role_id', config('permission.column_names.model_morph_key')
        );
    }


    /**
     * Find a role by its name and guard name.
     *
     * @param string $name
     * @param string|null $guardName
     *
     * @return \Spatie\Permission\Contracts\Role|\Spatie\Permission\Models\Role
     *
     * @throws \Spatie\Permission\Exceptions\RoleDoesNotExist
     */
    public static function findByName(string $name, $guardName = null): RoleContract {
        $guardName = $guardName ?? Guard::getDefaultName(static::class);


        $role = static::where('name', $name)->where('guard_name', $guardName)->first();


        if (!$role) {
            throw RoleDoesNotExist::named($name);
        }


        return $role;
    }


    public static function findById(int $id, $guardName = null): RoleContract {
        $guardName = $guardName ?? Guard::getDefaultName(static::class);


        $role = static::where('id', $id)->where('guard_name', $guardName)->first();


        if (!$role) {
            throw RoleDoesNotExist::withId($id);
        }


        return $role;
    }


    /**
     * Find or create role by its name (and optionally guardName).
     *
     * @param string $name
     * @param string|null $guardName
     *
     * @return \Spatie\Permission\Contracts\Role
     */
    public static function findOrCreate(string $name, $guardName = null): RoleContract {
        $guardName = $guardName ?? Guard::getDefaultName(static::class);


        $role = static::where('name', $name)->where('guard_name', $guardName)->first();


        if (!$role) {
            return static::query()->create(['name' => $name, 'guard_name' => $guardName]);
        }


        return $role;
    }


    /**
     * Determine if the user may perform the given permission.
     *
     * @param string|Permission $permission
     *
     * @return bool
     *
     * @throws \Spatie\Permission\Exceptions\GuardDoesNotMatch
     */
    public function hasPermissionTo($permission): bool {
        $permissionClass = $this->getPermissionClass();


        if (is_string($permission)) {
            $permission = $permissionClass->findByName($permission, $this->getDefaultGuardName());
        }


        if (is_int($permission)) {
            $permission = $permissionClass->findById($permission, $this->getDefaultGuardName());
        }


        if (!$this->getGuardNames()->contains($permission->guard_name)) {
            throw GuardDoesNotMatch::create($permission->guard_name, $this->getGuardNames());
        }


        return $this->permissions->contains('id', $permission->id);
    }


}


Go to this file again vendor/spatie/laravel-permission/src/Models/Permission and add protected $guard_name = 'web' .

Full Code


namespace Spatie\Permission\Models;


use Spatie\Permission\Guard;
use Illuminate\Support\Collection;
use Spatie\Permission\Traits\HasRoles;
use Illuminate\Database\Eloquent\Model;
use Spatie\Permission\PermissionRegistrar;
use Spatie\Permission\Traits\RefreshesPermissionCache;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Spatie\Permission\Exceptions\PermissionDoesNotExist;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Spatie\Permission\Exceptions\PermissionAlreadyExists;
use Spatie\Permission\Contracts\Permission as PermissionContract;


class Permission extends Model implements PermissionContract {


    use HasRoles;
    use RefreshesPermissionCache;


    protected $guarded = ['id'];
    protected $guard_name = 'web';


    public function __construct(array $attributes = []) {
        $attributes['guard_name'] = $attributes['guard_name'] ?? config('auth.defaults.guard');


        parent::__construct($attributes);


        $this->setTable(config('permission.table_names.permissions'));
    }


    public static function create(array $attributes = []) {
        $attributes['guard_name'] = $attributes['guard_name'] ?? Guard::getDefaultName(static::class);


        $permission = static::getPermissions(['name' => $attributes['name'], 'guard_name' => $attributes['guard_name']])->first();


        if ($permission) {
            throw PermissionAlreadyExists::create($attributes['name'], $attributes['guard_name']);
        }


        if (isNotLumen() && app()::VERSION < '5.4') {
            return parent::create($attributes);
        }


        return static::query()->create($attributes);
    }


    /**
     * A permission can be applied to roles.
     */
    public function roles(): BelongsToMany {
        return $this->belongsToMany(
                        config('permission.models.role'), config('permission.table_names.role_has_permissions'), 'permission_id', 'role_id'
        );
    }


    /**
     * A permission belongs to some users of the model associated with its guard.
     */
    public function users(): MorphToMany {
        return $this->morphedByMany(
                        getModelForGuard($this->attributes['guard_name']), 'model', config('permission.table_names.model_has_permissions'), 'permission_id', config('permission.column_names.model_morph_key')
        );
    }


    /**
     * Find a permission by its name (and optionally guardName).
     *
     * @param string $name
     * @param string|null $guardName
     *
     * @throws \Spatie\Permission\Exceptions\PermissionDoesNotExist
     *
     * @return \Spatie\Permission\Contracts\Permission
     */
    public static function findByName(string $name, $guardName = null): PermissionContract {
        $guardName = $guardName ?? Guard::getDefaultName(static::class);
        $permission = static::getPermissions(['name' => $name, 'guard_name' => $guardName])->first();
        if (!$permission) {
            throw PermissionDoesNotExist::create($name, $guardName);
        }


        return $permission;
    }


    /**
     * Find a permission by its id (and optionally guardName).
     *
     * @param int $id
     * @param string|null $guardName
     *
     * @throws \Spatie\Permission\Exceptions\PermissionDoesNotExist
     *
     * @return \Spatie\Permission\Contracts\Permission
     */
    public static function findById(int $id, $guardName = null): PermissionContract {
        $guardName = $guardName ?? Guard::getDefaultName(static::class);
        $permission = static::getPermissions(['id' => $id, 'guard_name' => $guardName])->first();


        if (!$permission) {
            throw PermissionDoesNotExist::withId($id, $guardName);
        }


        return $permission;
    }


    /**
     * Find or create permission by its name (and optionally guardName).
     *
     * @param string $name
     * @param string|null $guardName
     *
     * @return \Spatie\Permission\Contracts\Permission
     */
    public static function findOrCreate(string $name, $guardName = null): PermissionContract {
        $guardName = $guardName ?? Guard::getDefaultName(static::class);
        $permission = static::getPermissions(['name' => $name, 'guard_name' => $guardName])->first();


        if (!$permission) {
            return static::query()->create(['name' => $name, 'guard_name' => $guardName]);
        }


        return $permission;
    }


    /**
     * Get the current cached permissions.
     */
    protected static function getPermissions(array $params = []): Collection {
        return app(PermissionRegistrar::class)
                        ->setPermissionClass(static::class)
                        ->getPermissions($params);
    }


}


Next go to your Model where you use HasRoles and Paste this code , eg I used HasRoles in my User Model , will use the code on my user

Copy this code


 public function hasPermissionTo($permission, $guardName = 'web'): bool {


        $permissionClass = $this->getPermissionClass();


        if (is_string($permission)) {
            $permission = $permissionClass->findByName(
                    $permission, $guardName ?? $this->getDefaultGuardName()
            );
        }


        if (is_int($permission)) {
            $permission = $permissionClass->findById(
                    $permission, $guardName ?? $this->getDefaultGuardName()
            );
        }


        return $this->hasDirectPermission($permission) || $this->hasPermissionViaRole($permission);
    }


    protected function getDefaultGuardName(): string {
        return 'web';
    }


Now all web and API can use the same guard name to check user role and permission

See complete Code on my user model


namespace App\Models\User;


use Laravel\Passport\HasApiTokens;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Permission\Traits\HasRoles;


class User extends Authenticatable implements MustVerifyEmail {


    use HasApiTokens,
        SoftDeletes,
        HasRoles,
       ;


    public function hasPermissionTo($permission, $guardName = 'web'): bool {


        $permissionClass = $this->getPermissionClass();


        if (is_string($permission)) {
            $permission = $permissionClass->findByName(
                    $permission, $guardName ?? $this->getDefaultGuardName()
            );
        }


        if (is_int($permission)) {
            $permission = $permissionClass->findById(
                    $permission, $guardName ?? $this->getDefaultGuardName()
            );
        }


        return $this->hasDirectPermission($permission) || $this->hasPermissionViaRole($permission);
    }


    protected function getDefaultGuardName(): string {
        return 'web';
    }


    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'id', 'slug', 'username', 'email', 'email_verified_at', 'created_at', 'password',
    ];


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


    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
  

    protected $casts = [
        'email_verified_at' => 'datetime',
    ];



}


If this article help you kindly share , thanks for reading

Click Here To Comment


site


kizinho

Adike Kizito is a top-rated software developer, blogger, sports, and entertainment lover. He is the CEO of these popular websites Naijacrawl.com and Mp3ager.com. He operates his software developing task through Kizzsoft.com,... Read More

Continue Reading
Click to comment

Be first to comment


    Leave a Reply

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

    How to Download Instagram Photo and Video using PHP (easy way)

    kizinho

    Published

    on

    DEVELOPER PROGRAMMING: How to Download Instagram Photo and Video using PHP (easy way) [New  Developer Programming] » Naijacrawl
    Photo: Naijacrawl
    Hi folks, this script is really cool for those of you that want to get informations like photos and videos from Instagram, this tool is for you. Assuming you are working on a project that needs to get data from Instagram just follow these steps and get it done. Step 1 Download this package using the following command  composer requireayeshinstagram-download  Step 2  Set your Instagram photo or video URLs as show below  getDownloadUrl(); // Returns the download URL....
    Continue Reading

    Laravel 9.18.0 New Features Detailed

    kizinho

    Published

    on

    DEVELOPER PROGRAMMING: Laravel 9.18.0 New Features Detailed [New  Developer Programming] » Naijacrawl
    Photo: Naijacrawl
    Laravel 9.18.0 comes with a new feature that you will love to upgrade and use, the new features come with 4 main features shipped.Rule objectsQuery timeAttachable objects Nested eager load syntaxRule objects rules that make it simpler to define custom validation rules using simple, single method invokable objects. Very similar API to Closure rules.Query timeintroduced a new method that invokes a closure if cumulative time you spend querying the database during a req...
    Continue Reading

    Mastering laravel Routes

    kizinho

    Published

    on

    DEVELOPER PROGRAMMING: Mastering laravel Routes [New  Developer Programming] » Naijacrawl
    Photo: Naijacrawl
    Hi, folks, we have successfully mastered MVC in the last class, if you missed it go back here.We have talked about routes and where they can be found in the project, will do a quick freshened up in routes.Laravel routes simply accept a URI and a Closure, providing a very simple and expressive method of defining routes:Before we start using a route, take note of the following :Available Router Methodsget - you use get when you want to get resources from the databasep...
    Continue Reading

    Latest


    Download Naijacrawl App today

    Fastest way to read on the go

    Download the Naijacrawl App.