Laravel 用户权限管理

实现基于user,role,permission三表的权限管理 因为一个用户可能拥有多种role,而一种role能同时被多个用户拥有。所以要建立多对多关系。 参见文档

  1. 建立这三个表及关联表
    public function up()
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('label')->nullable();
            $table->timestamps();
        });

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

        Schema::create('permission_role', function (Blueprint $table) {
            $table->integer('permission_id')->unsigned();
            $table->integer('role_id')->unsigned();

            $table->foreign('permission_id')
                  ->references('id')
                  ->on('permissions')
                  ->onDelete('cascade');

            $table->foreign('role_id')
                  ->references('id')
                  ->on('roles')
                  ->onDelete('cascade');

            $table->primary(['permission_id', 'role_id']);
        });

        Schema::create('role_user', function (Blueprint $table) {
            $table->integer('role_id')->unsigned();
            $table->integer('user_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']);
        });
    }
  1. 建立模型关联

User模型

...
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
...

Role模型

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

    // $role = Role::first(); $p = Permission::first();  
    // $role->givePermission($p);
    public function givePermission(Permission $permission)
    {
        return $this->permissions()->save($permission);
    }
}

Permission模型

class Permission extends Model
{
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }
}
  1. 添加记录,这里我们添加一个admin的role和名为edit_form的permission,并且让admin拥有edit_form权限。

image.png

执行完 $role->givePermission($permission);会发现permission_role表多了一条记录

image.png

添加role和user的关系,将id为1的用户角色修改为admin。

image.png

会发现role_user表多了一条记录

image.png

$user->roles()->detach($role); 可以删除这条记录 $user->roles()->attach($role); 新增记录

  1. 修改AuthServiceProvider.php,从数据库从读取所有的permission信息并设置Gate。让配置生效。
    public function boot()
    {
        $this->registerPolicies();

        // Gates 接受一个用户实例作为第一个参数,并且可以接受可选参数,比如 相关的 Eloquent 模型:
        foreach($this->getPermission() as $permission) {
            // dd($permission->roles);
            Gate::define($permission->name, function($user) use ($permission) {
                // 返回collection
                return $user->hasRole($permission->roles);
            });
        }

    }

    public function getPermission()
    {
        return Permission::with('roles')->get();
    }

给User模型添加hasRole方法

    public function hasRole($role)
    {
        if (is_string($role)) {
            return $this->roles->contains('name', $role);
        }

        // intersect 移除任何指定 数组 或集合内所没有的数值。最终集合保存着原集合的键:
        return !!$role->intersect($this->roles)->count();
    }
  1. 修改视图,测试,如果当前登录用户的id是1,就可以看到'编辑'链接
@can('edit_form')
<a href="#">编辑</a>
@endcan
  1. 总结

$this->roles() 与 $this->roles 有什么不同,什么情况下使用呢? $this->roles() 返回 QueryBuilder ,$this->roles 返回一个 Collection

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Spark学习技巧

Kafka源码系列之分组消费的再平衡策略

一,Kafka消费模式 从kafka消费消息,kafka客户端提供两种模式: 分区消费,分组消费。 分区消费对应的就是我们的DirectKafkaInputDS...

1.1K60
来自专栏刘望舒

Android内存优化(五)详解内存分析工具MAT

前言 在这个系列的前四篇文章中,我分别介绍了DVM、ART、内存泄漏和内存检测工具的相关知识点,这一篇我们通过一个小例子,来学习如何使用内存分析工具MAT。 ...

49580
来自专栏信安之路

PE 病毒与 msf 奇遇记

通俗的讲,PE 病毒就是感染 PE 文件的病毒,通过修改可执行文件的代码中程序入口地址,变为恶意代码的的入口,导致程序运行时执行恶意代码。

11900
来自专栏红色石头的机器学习之路

Jupyter notebook入门教程(上)

本文将分上下两部分简单介绍Jupyter notebook的入门教程,英文原文出处: Getting started with the Jupyter note...

42000
来自专栏前端儿

前端实现文件的断点续传

以前文件无法分割,但随着HTML5新特性的引入,类似普通字符串、数组的分割,我们可以可以使用slice方法来分割文件。

80420
来自专栏青青天空树

MIME协议在邮件中的应用详解

  全称是多用途互联网邮件扩展(MIME,Multipurpose Internet Mail Extensions),在MIME出台之前,使用RFC 822只...

21010
来自专栏技术博客

Asp.Net Web API 2第十五课——Model Validation(模型验证)

阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.h...

10620
来自专栏容器云生态

Docker-client for python使用指南

Docker-client for python使用指南: 客户端初始化的三种方法 import docker docker.api() docker.APIC...

1.3K100
来自专栏大内老A

框架升级后某个类型所在程序集发生转移,应用还能正常运行吗?

所谓类型转移(Type Forwarding)就是将定义在某个程序集中的类型转移到另一个程序集中。我们先通过一个简单的实例让读者朋友们对类型转移有一个感官上的认...

19460
来自专栏Linux驱动

第1阶段——uboot分析之启动函数bootm命令 (9)

本节主要学习: 详细分析UBOOT中"bootcmd=nand read.jffs2 0x30007FC0 kernel;bootm 0x30007FC0...

19750

扫码关注云+社区

领取腾讯云代金券