TP5 + mongodb数据库 + auth 权限验证

浏览:2913 发布日期:2017/01/16 分类:ThinkPHP5专区 关键字: TP5 mongodb auth
我看了大多数文章都是THINKPHP +MYSQL 数据库
如果使用 mongo 3.2 数据库 + THINKPHP 5 会怎样?
好多问题要解决,比如 Auth

经过一段时间的研究,搞定了。实现方法如下:
ThinkPHP 5.0 MongoDb驱动安装
===============
首先安装官方的mongodb扩展:
http://pecl.php.net/package/mongodb
或者
> composer require topthink/think-mongo

接下来安装 Auth
> composer require 5ini99/think-auth
或者将 think-auth 目录复制到 vendor/topthink 下

还要更改 think-auth/src/Auth.php 用于适应 mongo 驱动的要求
大约在第 188行的 getGroups 函数需要更改
将如下代码:// 转换表名
        $auth_group_access = Loader::parseName($this->config['auth_group_access'], 1);
        $auth_group = Loader::parseName($this->config['auth_group'], 1);
        //执行查询
        $user_groups = Db::view($auth_group_access, 'uid,group_id')
            ->view($auth_group, 'title,rules', "{$auth_group_access}.group_id={$auth_group}.id", 'LEFT')
            ->where("{$auth_group_access}.uid='{$uid}' and {$auth_group}.status='1'")
            ->select();
更换成:// 转换表名
        $auth_group_access ='app\\common\\model\\' .Loader::parseName($this->config['auth_group_access'], 1);
        $auth_group = Loader::parseName($this->config['auth_group'], 1);
         //执行查询
       $table1 = new $auth_group_access();
       $temp = $table1->relation($auth_group)->where('uid',$uid)->select();
       $user_groups = [];
       $t = [];
       foreach ($temp as $key => $value) {
           $t=$value->toArray();
           if($t[$auth_group]['status']==1 && !empty($t[$auth_group]['rules'])) {
               unset($t[$auth_group]['id']);
               $t=array_merge($t,$t[$auth_group]);
               unset($t[$auth_group]);
               $user_groups[$key] = $t;
          }
       }
再找到如下代码:$map = array(
            'id' =>['in', $ids],
            'type' => $type,
            'status' => 1,
        );
改成:$map = array(
            'id' =>['in', array_values($ids)],
            'type' => $type,
            'status' => 1,
             'level' => 1,//规则的标识,区分其他数据。根据个人需要可以删除这个
        );
这样 Auth.php 就改好了。

## 配置文件
### 公共配置 或者 模块的配置
// auth配置 这个可在模块下的 config.php 中设置
// 例如可在 admin/config.php 中设置后,只对该模块起作用
'auth' => [
'auth_on' => 1, // 权限开关
'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。
'auth_group' => 'auth_group', // 用户组数据不带前缀表名
'auth_group_access' => 'auth_group_access', // 用户-用户组关系不带前缀表名
'auth_rule' => 'auth_rule', // 权限规则不带前缀表名
'auth_user' => 'admin', // 用户信息不带前缀表名
],

Mongo 数据库中的数据集结构如下,具体怎么操作增删改查自己去做吧
------------------------------
-- think_auth_rule,规则表,
-- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证
------------------------------
有2中形式第一种是标准的规则条目数据 如下
{
"_id":{"$oid":"58749d2e42e5fb1d0c001945"},
"pid":"58749ce942e5fb1d0c001942", //父节点的ID
"pname":"admin-amenu", //父节点的名称用于显示父级名称,也是用于生成子节点的前缀
"title":"添加菜单",
"name":"admin-amenu-add",
"condition":"",
"type":1, // 类型为1 是实时权限 为2 是登陆检测权限 注意是整数型的,在存入数据的时候要注意
"status":1, // 为1正常,为0禁用 用于标识这个是有效的规则数据 注意是整数型的,在存入数据的时候要注意
"level":1, //用以标识有效的规则记录 注意是整数型的,在存入数据的时候要注意
"update_time":1484284932,
"create_time":1484037422
}
第二种形式是子权限的父节点,这个在权限控制中是不需要的,只是用于分组的需求,根据个人的情况可以不考虑这样的数据条目
{
"_id":{"$oid":"58748cd042e5fb1d0c001938"},
"pid":"3",
"pname":"admin",
"title":"后台首页",
"name":"admin-index",
"update_time":1484033232,
"create_time":1484033232
}


------------------------------
-- think_auth_group 用户组表,
-- id:主键, title:用户组中文名称, rules:用户组拥有的规则id, 多个规则","隔开,status 状态:为1正常,为0禁用
------------------------------
{
"_id":{"$oid":"584511fa42e5fb00d8000517"},
"title":"一般管理员",
"status":"1",
"rules":"58748ded42e5fb1d0c00193a,587490ff42e5fb1d0c00193c,58749d0742e5fb1d0c001943,5874a67142e5fb1d0c00194b,5874a7d142e5fb1d0c001956,5874a78a42e5fb1d0c001952",
"update_time":1484385532,
"create_time":1480921594
}

------------------------------
-- think_auth_group_access 用户组明细表
-- uid:用户id,group_id:用户组id
------------------------------
{
"_id":{"$oid":"5878f916f0e42213f0003c3c"},
"uid":"5805864742e5fb3294000942",
"group_id":"584511fa42e5fb00d8000517"
}

------------------------------
-- think_zsjt_admin 用户表
-- uid:用户id,不详细介绍了
------------------------------
{
"_id":{"$oid":"5805864742e5fb3294000942"},
"username":"lijing",
"nickname":"xxxxx",
"email":"dfs@xxxxxxx.com",
"passtype":"0",
"password":"a1fa34055727d6dc25f4dbf94d88fe58",
"status":"1",
"islock":"0",
"update_time":1484382657,
"create_time":1476757063
}

下面是建立几个模型,用于一对多关联和一对一关联
AuthGroupAccess用户和用户组关联表<?php
namespace app\common\model;
use think\Model;
class AuthGroupAccess extends Model
{
    protected $pk = 'id';
//关联查询  一对一     名称可以随便起  但是 hasOne 中的第一个参数必须是数据集名称
 //用法 $this->table->relation('AdminAuthGroup')->where('id',$id)
 //关联到 用户组模型
 public function AdminAuthGroup()
    {
        return $this->hasOne('AdminAuthGroup','id','group_id')->field('title,rules,status');
    }
}
Admin 后台用户的 USER 表模型<?php
namespace app\common\model;
use think\Model;
class Admin extends Model
{
    protected $pk = 'id';
    protected $auto = [];
    //设置在插入数据时自动完成字段设置
    protected $insert = ['status' => false,'islock'=>false,'passtype'=>0];
    //修改器 自动将密码转成MD5
    public function setPasswordAttr($value) //修改器
    {
        return md5($value);
    }
    //修改器  设置自动返回用户IP
    public function setIpAttr()
    {
              return request()->ip();
    }
    //一对多关联到用户组表 可以是多个组成员
public function groups()
    {
        //hasMany('关联模型名','外键名','主键名',['模型别名定义']);   一对多
        //field    指定查询字段 用逗号隔开
        return $this->hasMany('AuthGroupAccess','uid','id')->field('group_id');
    }
}
AdminAuthGroup用户组表模型<?php
namespace app\common\model;
use think\Model;
class AdminAuthGroup extends Model
{
    protected $pk = 'id';
}
然后是自己动手做几个控制器添加相关数据到数据库
下面就可以用Auth 验证权限了

## 原理
Auth权限认证是按规则进行认证。

- 规则表(think_admin_auth_rule)
- 用户组表(think_admin_auth_group)
- 用户和用户组关联表(think_auth_group_access) 一个用户可以属于多个组
- 用户表(think_admin) 一个用户可以属于多个组

控制器中添加一个 base 控制器 ,其他需要权限验证的控制器继承这个控制器就可以了<?php
use think\Controller;
use think\auth\Auth;
class Base extends Controller
{
    public function _initialize()
    {

            $module = strtolower(request()->module());
           $controller = strtolower(request()->controller());
            $action = strtolower(request()->action());

            $auth = new Auth();
            //除了 admin 管理员外其他都要验证权限
            //登录成功后将用户名存到 session('username','','admin') 中
            //将用户ID 存到 session(config('admin_auth_key'),'', 'admin')中
            //config('admin_auth_key')是我在config.php中自己添加的设置方便调用
            if(session('username','','admin') != 'admin' &&  !$auth->check($module.'-'.$controller . '-' . $action, session(config('admin_auth_key'),'', 'admin'))){
                $this->error('你没有权限访问');
            }
    }
 }
再上几个图看看我的实现




最佳答案
评论( 相关
后面还有条评论,点击查看>>