Laravel5.1 将控制权限存储到数据库

上一篇文章记录了如何使用policy,一般要做一个完整的网站我们需要把一系列的管理权限存储到数据库中,这样就可以更加灵活的使用用户控制权限,首先我们来创建两个模型 permission(权限)和role(角色):

 php artisan make:model Permission 
 php artisan make:model Role 

逻辑关系

上面我们创建了权限和角色模型,现在我们来生成对应的数据表,但是要先想清楚它们之间的关系,一个权限可以被很多个用户使用,一个用户又可以有很多的权限,很明显这是一个多对多的关系,那么我们就需要在迁移文件中创建第三张关系表。

为了方便我就在一个migration中创建3张表咯:

php artisan make:migration create_permission_role_table --create=roles
    public function up()
    {
        // 创建角色表
        Schema::create(‘roles‘, function (Blueprint $table) {
            $table->increments(‘id‘);
            $table->string(‘name‘);                     // 角色的名字,比如 admin 和 number
            $table->string(‘lable‘)->nullable();        // 角色的标签(可空)
            $table->timestamps();
        });

        // 创建权限表
        Schema::create(‘permissions‘, function (Blueprint $table) {
            $table->increments(‘id‘);
            $table->string(‘name‘);                     // 权限的名字,比如 update 和 delete
            $table->string(‘lable‘)->nullable();        // 权限的标签(可空)
            $table->timestamps();
        });

        // 创建多对多关联表
        Schema::create(‘permission_role‘, function (Blueprint $table) {
            $table->integer(‘permission_id‘)->unsigned();
            $table->integer(‘role_id‘)->unsigned();

            // 声明permisstion_id外键
            $table->foreign(‘permission_id‘)
                  ->references(‘id‘)
                  ->on(‘permissions‘)
                  ->onDelete(‘cascade‘);
            // 声明role_id外键
            $table->foreign(‘role_id‘)
                  ->references(‘id‘)
                  ->on(‘roles‘)
                  ->onDelete(‘cascade‘);

            // 设置主键
            $table->primary([‘permission_id‘,‘role_id‘]);
        });
    }

这样我们的多对多关系就设置好了,但是还不够,我们需要对user表和roles表添加关系,所以我们在添加一张表

        // 创建user和role的关联表
        Schema::create(‘user_role‘, function (Blueprint $table) {
            $table->integer(‘user_id‘)->unsigned();
            $table->integer(‘role_id‘)->unsigned();

            // 声明user_id外键
            $table->foreign(‘user_id‘)
                ->references(‘id‘)
                ->on(‘users‘)
                ->onDelete(‘cascade‘);
            // 声明role_id外键
            $table->foreign(‘role_id‘)
                ->references(‘id‘)
                ->on(‘roles‘)
                ->onDelete(‘cascade‘);

            // 设置主键
            $table->primary([‘user_id‘,‘role_id‘]);
        });

现在我们就可以生成表啦:

 php artisan migrate 

在模型中声明多对多关系

刚刚在表中实现了多对多关系,现在我们在模型中来创建多对多的关系,首先是permission模型:

Permission模型

class Permission extends Model
{
    public function roles()
    {
        // 这里使用belongsToMany而不是belongsTo,因为它们是多对多关系
        return $this->belongsToMany(Role::class);
    }
}

Role模型

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

在Role中我们在声明一个方法:

    // 给予权限
    public function givePermission(Permission $permission)
    {
        return $this->permissions()->save($permission);
    }

User模型

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

生成数据

我们在tinker中生成数据,进入tinker后编写:

>>> namespace App;
=> null
>>> $role = new Role();
=> App\Role {#665}
>>> $role->name = ‘admin‘;
=> "admin"
>>> $role->lable = ‘Admin‘;
=> "Admin"
>>> $role->save();
=> true
>>> $permission = new Permission;
=> App\Permission {#669}
>>> $permission->name = ‘edit_form‘;
=> "edit_form"
>>> $permission->lable = ‘Edit The Form‘;
=> "Edit The Form"
>>> $permission->save();
=> true

以上已经在数据库中添加了两条数据,但是并没有在关联表中添加,不过我们已经声明了givePermission方法,我们在tinker中直接添加:

>>> $role->givePermission($permission);

观察我们的数据库,我们现在已经添加了关联关系。

开始测试

我们现在就来添加控制权限,打开AuthServiceProvider,进入boot方法添加以下代码:

    public function boot(GateContract $gate)
    {
        $this->registerPolicies($gate);

        // 循环取出权限
        foreach (Permission::with(‘roles‘)->get() as $permission){
            $gate->define($permission->name, function (User $user) use ($permission){
                return $user->hasRole($permission->roles);
            });
        }
    }

在user中声明hasRole方法:

    public function hasRole($role)
    {
        if (is_string($role)){
            // 是否存在这个字符串(名字)
            return $this->roles->contains($role);
        }
        return !! $role->intersect($this->roles)->count();
    }

只是我们现在的user_role表还没有数据 我们在tinker创建下:

>>> $role = App\Role::first();
=> App\Role {#659
     id: 1,
     name: "admin",
     lable: "Admin",
     created_at: "2017-03-25 04:54:55",
     updated_at: "2017-03-25 04:54:55",
   }
>>> $user = App\User::first();
=> App\User {#661
     id: 1,
     name: "Dorcas Johnston",
     email: "[email protected]",
     created_at: "2017-03-25 04:53:00",
     updated_at: "2017-03-25 04:53:00",
   }
>>> $user->roles()->save($role);
=> App\Role {#659
     id: 1,
     name: "admin",
     lable: "Admin",
     created_at: "2017-03-25 04:54:55",
     updated_at: "2017-03-25 04:54:55",
   }

我们返回view来查看结果:

    public function index()
    {
        \Auth::loginUsingID(2);
        $post = Post::findOrFail(1);
        return view(‘show‘, compact(‘post‘));
    }

show.blade.php的代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
</head>
<body>
    <h1>{{ $post->title }}</h1>
    @can(‘edit_form‘)
    <a href="#">编辑</a>
    @endcan
</body>
</html>

我们登陆的是id为2的用户,这个用户没有admin的角色 所以不会显示编辑链接,但是我们登陆id为1的用户 就会显示编辑链接。

时间: 2024-07-30 13:34:34

Laravel5.1 将控制权限存储到数据库的相关文章

在hue当中设置hive当中数据库的控制权限。

这段时间在搞大数据的集群搭建工作,并且安装了hive的服务,但是没有对其中的数据库的操作权限做限制,每个人都可以对数据库进行增删改查.今天有空做了一下了对hive数据库当中的数据库做一些限制. 我们都是在hue的客户端进行操作hive当中的数据库.操作如下: (1)在hue界面创建登录用户: (2)   配置hive权限控制 <property> <name>hive.security.authorization.enabled</name> <value>

物理数据库设计 - 文件是否应该存储在数据库中

多媒体文件已经广泛应用在很多程序当中.比如用户的头像,汽车的产品图片等等. 从我个人以往的经验来看,将文件的路径存储入数据库,然后文件本身存储于硬盘当中已是万年不变的解决方案. 其实,存储图片路径与存储图片文件本身,两种方案都有很好的立足点,但是大部分程序员都是将文件存储于数据库之外.虽然,这种方法没有什么大问题,但的确是存在一定的风险的. 一.问题描述 下面就来论述一下关于将文件存储于数据库外部的缺点. 1.垃圾回收问题. 当你想删除一张图片时,你只能够删除掉数据库中的记录,图片文件是没有办法

如何将类序列化并直接存储入数据库

参考代码1 可以使用.net提供的序列化和反序列化方法来实现,你可将对象序列化成XML字符串,然后存入数据库中,当你要使用对象的时候,再把数据库中保存字符串反序列化成对象就可以使用了,以下为示例代码: public class Cat { public string Color { get; set; } public int Speed { get; set; } public string Name{ get; set; } } //序列化 var cat1=new Cat{Color="W

如何使用 JDBC 调用存储在数据库中的函数或存储过程

JDBC调用存储过程步骤:1 通过Connection对象的prepareCall()方法创建一个CallableStatement对象的实例.在使用Connection对象的prepareCall()方法时,需要传入一个String类型的字符串,该字符串用于指明如何调用存储过程{?= call <procedure-name>[(<arg1>,<arg2>, ...)]} {call <procedure-name>[(<arg1>,<a

SharePoint 2010 系统账户没完全控制权限了

网上下载了一个试用版的wsp包,安装部署后感觉不好就卸载掉了.坑爹的事情发生了,系统账户登录网站集竟然没完全控制权限了.连添加列表项的权限都没有了. 去管理中心查看,网站集管理员,没发现问题. 更坑爹的是在管理中心,系统账户权限一切正常.google一圈才发现,网站集莫名其妙的改为只读状态了. 管理中心-----应用程序管理----配置配额和锁定 解决办法:选'未锁定',然后确定即可. SharePoint 2010 系统账户没完全控制权限了,布布扣,bubuko.com

C#修改文件或文件夹的权限,为指定用户、用户组添加完全控制权限

题目链接:11645 - Bits 题意:给定一个数字n,要求0-n的二进制形式下,连续11的个数. 思路:和 UVA 11038 这题类似,枚举中间,然后处理两边的情况. 不过本题最大的答案会超过longlong,要用高精度,不过借鉴http://www.cnblogs.com/TO-Asia/p/3214706.html这个人的方法,直接用两个数字来保存一个数字,这样能保存到2个longlong的长度,就足够存放这题的答案了. 代码: #include <stdio.h> #include

Python爬虫:爬取小说并存储到数据库

爬取小说网站的小说,并保存到数据库 第一步:先获取小说内容 #!/usr/bin/python # -*- coding: UTF-8 -*- import urllib2,re domain = 'http://www.quanshu.net' headers = {     "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrom

TJI读书笔记09-访问控制权限

body, td { font-family: 微软雅黑; font-size: 10pt; } TJI读书笔记09-访问控制权限 包,package和import 权限修饰符 接口和实现 类的访问权限控制 首先问一个问题,为什么要有访问控制权限? 安全,这当然是一个很重要的原因. 让类库的使用者只能接触他做需要接触的东西. 另外一方面,当我们去重构和修改代码的时候,如何不影响其他的代码和功能?权限访问控制是可以很好的将"变动的事物"和"不变的事物"区分开来.比如一

问卷过程_将编辑好的问卷(存储在数据库中)显示在浏览器中

首先要了解数据的设计,也就是数据室怎么存储在数据库中的. 先来看一个最简单的问卷的构成吧 可以看到大概的结构是:『标题:标题内容标题说明.题目:题目编号,题目内容.选项:选项类型,选项编号,选项内容』.提交:提交按钮.其中『』内的元素就是需要存储到数据库中的. 可以想一下:一张表示是否可以存储一张问卷呢?这应该是可以的但是一个表不应该只能存储一张问卷吧,要不然太浪费资源了. 数据库的设计应该是怎样的呢: 首先:整体的问卷基本信息要有:问卷的编号(我们通过链接把我们的问卷发给别人来填写的话,要唯一