关于权限管理的思考

最近用laravel设计后台,后台需要有个权限管理。权限管理实质上分为两个部分,首先是认证,然后是权限。认证部分非常好做,就是管理员登录,记录session。这个laravel中也有自带Auth来实现这个。最麻烦就是权限认证。

权限认证本质上就是谁有权限管理什么东西。这里有两个方面的维度,谁,就是用户维度,在用户维度,权限管理的粒度可以是用户一个人,也可以是将用户分组,如果将用户分组,则涉及到的逻辑是一个用户可以在多个组里面吗?在另外一方面,管理什么东西,这个东西是物的维度,一个页面是一个东西,一个页面上的一个元素也是一个东西,或者往大了说,一个功能是一个东西。所以做权限管理最重要的是确认这两个维度的粒度。这个已经不是技术的事情了,这个是需要需求讨论的了。

基于上面的思考,我这次想做的权限管理,在用户维度,是基于个人的。就是每个人的权限不一样。在东西的维度,我设置路由为最小的单位,即可以为单个路由设置权限管理。

下面的思考就是使用什么来标记权限,可以使用位,也可以使用字符,也可以使用整型。后来我选择了字符,基于两点考虑:1 字符浅显易懂,在数据库中查找也比较方便 2 我没有按照某个权限查找有这个权限的人的需求,即没有反查需求,使用位,整型等都意义不大。

接下来考虑如何和laravel结合,既然要为每个路由设置访问权限,那么我当然希望能在laravel的route.php路由管理中配置。最好就是在Route::get的时候有个参数能设置permission。这样做的好处是权限设置简易了。在决定路由的时候,就顺手写了权限控制。坏处呢,也很明显,laravel路由的三种方式只能写一种了。就是Route::(method)这样的方式了。

基本决定好了就开干。

路由设计

基本的路由是这样的

Route::post('/admin/validate', ['uses' => 'AdminController@postValidate', 'permissions'=>['admin.validate', 'admin.index']]);

这里在基本的制定路由action之后设置了一个permissions的属性,这个属性设计成数组,因为比如一个post请求,它可能在某个页面会触发,也可能在另外一个页面触发,那么这个post请求就需要同时拥有两个页面路由的权限。

这里使用admin.validate的权限控制,这样,可以将权限分组,admin都是关于admin相关的分组,在数据库中,我就会存储一个二维数组,[admin] => ['validate', 'index']; 存储成二维数组而不是一维的好处呢,一般后台展示是有两个维度的,一个是头部的tab栏,一个是左边的nav栏,就是说这个二维的数组和后台的tab,nav栏是一一对应的。

中间件设计

好了,下面我们就挂上中间件,并且设置所有的路由都走这个中间件

<?php namespace App\Http\Middleware;

use Illuminate\Support\Facades\Session;
use Closure;

class Permission {

  /**
   * Handle an incoming request.
   *
   * @param \Illuminate\Http\Request $request
   * @param \Closure $next
   * @return mixed
   */
  public function handle($request, Closure $next)
  {
    $permits = $this->getPermission($request);

    $admin = \App\Http\Middleware\Authenticate::getAuthUser();

    // 只要有一个有权限,就可以进入这个请求
    foreach ($permits as $permit) {
      if ($permit == '*') {
        return $next($request);
      }
      if ($admin->hasPermission($permit)) {
        return $next($request);
      }
    }

    echo "没有权限,请联系管理员";exit;
  }

  // 获取当前路由需要的权限
  public function getPermission($request)
  {
    $actions = $request->route()->getAction();
    if (empty($actions['permissions'])) {
      echo "路由没有设置权限";exit;
    }
    return $actions['permissions'];
  }
}

这里最关键的就getPermission函数,从$request->route()->getAction()来获取出这个路由的action定义,然后从其中的permissions字段中获取route.php中定义的路由权限。

然后上面的middleware有个admin−>hasPermission(permit); 这个就涉及到model的设计。

model设计

<?php namespace App\Models\Admin;

use App\Models\Model as BaseModel;

class Admin extends BaseModel {

  protected $table = 'admin';

  // 判断是否有某个权限
  public function hasPermission($permission)
  {
    $permission_db = $this->permissions;
    if(in_array($permission, $permission_db)) {
      return true;
    }

    return false;
  }

  // permission 是一个二维数组
  public function getPermissionsAttribute($value)
  {
    if (empty($value)) {
      return [];
    }
    $data = json_decode($value, true);
    $ret = [];
    foreach ($data as $key => $value) {
      $ret[] = $key;
      foreach ($value as $value2) {
        $ret[] = "{$key}.{$value2}";
      }
    }
    return array_unique($ret);
  }

  // 全局设置permission
  public function setPermissionsAttribute($value)
  {
    $ret = [];
    foreach ($value as $item) {
      $keys = explode('.', $item);
      if (count($keys) != 2) {
        continue;
      }
      $ret[$keys[0]][] = $keys[1];
    }

    $this->attributes['permissions'] = json_encode($ret);
  }
}

在数据库中,我将二维数组存储为json,利用laravel的Attribute的get和set方法,完成了数据库中json和外界程序逻辑的连接。然后hasPermission就显得很轻松了,直接判断in_array就ok了。

后续

这个权限认证的逻辑就清晰了。然后如果页面中某个tab或者nav需要对不同权限的用户展示,只需要在view中判断

@if ($admin->hasPermission('admin.index')) 
@endif

就可以判断这个用户是否可以看到这个tab了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Devmax。

laravel实现简单用户权限的示例代码的更多相关文章

  1. Laravel自动生成UUID,从建表到使用详解

    今天小编就为大家分享一篇Laravel自动生成UUID,从建表到使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  2. laravel框架模型中非静态方法也能静态调用的原理分析

    这篇文章主要介绍了laravel框架模型中非静态方法也能静态调用的原理,结合实例形式分析了laravel模型基类中使用魔术方法实现非静态方法进行静态调用的相关原理,需要的朋友可以参考下

  3. Laravel相关的一些故障解决

    这篇文章主要给大家介绍了关于Laravel相关的一些故障的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者使用Laravel具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

  4. Laravel框架中缓存的使用方法分析

    这篇文章主要介绍了Laravel框架中缓存的使用方法,结合具体实例形式分析了Laravel框架中缓存的常用方法、操作步骤及相关使用操作技巧,需要的朋友可以参考下

  5. laravel 实现设置时区的简单方法

    今天小编就为大家分享一篇laravel 实现设置时区的简单方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  6. laravel框架学习记录之表单操作详解

    这篇文章主要介绍了laravel框架学习记录之表单操作,结合实例形式详细分析了laravel框架表单操作相关的路由请求、视图、资源、渲染、表单验证、错误记录等实现方法与操作注意事项,需要的朋友可以参考下

  7. Laravel框架基础语法与知识点整理【模板变量、输出、include引入子视图等】

    这篇文章主要介绍了Laravel框架基础语法与知识点整理,包括模板变量、输出、include引入子视图等相关操作技巧,需要的朋友可以参考下

  8. Laravel使用支付宝进行支付的示例代码

    本篇文章主要介绍了Laravel使用支付宝进行支付的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. Laravel开启跨域请求的方法

    今天小编就为大家分享一篇Laravel开启跨域请求的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  10. Laravel 重写日志,让日志更优雅

    这篇文章主要介绍了Laravel 重写日志,让日志更优雅,laravel框架俗称优雅的框架,所以有想对laravel中的日志重写使其更加方便的记录信息获取信息的同学可以参考下

随机推荐

  1. PHP个人网站架设连环讲(一)

    先下一个OmnihttpdProffesinalV2.06,装上就有PHP4beta3可以用了。PHP4给我们带来一个简单的方法,就是使用SESSION(会话)级变量。但是如果不是PHP4又该怎么办?我们可以假设某人在15分钟以内对你的网页的请求都不属于一个新的人次,这样你可以做个计数的过程存在INC里,在每一个页面引用,访客第一次进入时将访问时间送到cookie里。以后每个页面被访问时都检查cookie上次访问时间值。

  2. PHP函数学习之PHP函数点评

    PHP函数使用说明,应用举例,精简点评,希望对您学习php有所帮助

  3. ecshop2.7.3 在php5.4下的各种错误问题处理

    将方法内的函数,分拆为2个部分。这个和gd库没有一点关系,是ecshop程序的问题。会出现这种问题,不外乎就是当前会员的session或者程序对cookie的处理存在漏洞。进过本地测试,includes\modules\integrates\ecshop.php这个整合自身会员的类中没有重写integrate.php中的check_cookie()方法导致,验证cookie时返回的username为空,丢失了登录状态,在ecshop.php中重写了此方法就可以了。把他加到ecshop.php的最后面去就可

  4. NT IIS下用ODBC连接数据库

    $connection=intodbc_connect建立数据库连接,$query_string="查询记录的条件"如:$query_string="select*fromtable"用$cur=intodbc_exec检索数据库,将记录集放入$cur变量中。再用while{$var1=odbc_result;$var2=odbc_result;...}读取odbc_exec()返回的数据集$cur。最后是odbc_close关闭数据库的连接。odbc_result()函数是取当前记录的指定字段值。

  5. PHP使用JpGraph绘制折线图操作示例【附源码下载】

    这篇文章主要介绍了PHP使用JpGraph绘制折线图操作,结合实例形式分析了php使用JpGraph的相关操作技巧与注意事项,并附带源码供读者下载参考,需要的朋友可以参考下

  6. zen_cart实现支付前生成订单的方法

    这篇文章主要介绍了zen_cart实现支付前生成订单的方法,结合实例形式详细分析了zen_cart支付前生成订单的具体步骤与相关实现技巧,需要的朋友可以参考下

  7. Thinkphp5框架实现获取数据库数据到视图的方法

    这篇文章主要介绍了Thinkphp5框架实现获取数据库数据到视图的方法,涉及thinkPHP5数据库配置、读取、模型操作及视图调用相关操作技巧,需要的朋友可以参考下

  8. PHP+jquery+CSS制作头像登录窗(仿QQ登陆)

    本篇文章介绍了PHP结合jQ和CSS制作头像登录窗(仿QQ登陆),实现了类似QQ的登陆界面,很有参考价值,有需要的朋友可以了解一下。

  9. 基于win2003虚拟机中apache服务器的访问

    下面小编就为大家带来一篇基于win2003虚拟机中apache服务器的访问。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Yii2中组件的注册与创建方法

    这篇文章主要介绍了Yii2之组件的注册与创建的实现方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下

返回
顶部