codecamp

Auth 权限扩展 (由@黄苗笋提供)

Auth 权限扩展使用文档

页面历史

前言

首先要说明一个问题,有很多同学都会对Auth和OAuth这名称特别相似的东西傻傻分不清楚,但实际这是两个概念,Auth扩展指的是实现了基于用户与组的权限认证功能,与RBAC权限认证类似,主要用于对服务级别的功能进行权限控制,而OAuth,大概可以理解为接口签名认证。

如果有开发网站后台或者管理系统经验的同学应该明白权限认证的重要性,所以基于这个情况,我就写了这个扩展,当然,这个扩展是移植于TP的Auth类,并做了相关的优化,也提供了相关操作的Api接口, 并没有什么技术性,希望能帮助并方便到大家。

我并不是一个专业的phper,只是出自于自己对这份事情的爱好,所以在编码的规范,代码的使用上或许存在不少的弊端,也希望赏脸用了这个扩展类的同学,多提宝贵意见。让我不断地进步。

了解Auth权限认证

想要详细了解Auth权限认证的思路,请移步 比RBAC更好的权限认证方式(Auth类认证)
在此我就不过多地对Auht本身进行说明了。

安装

(1)、扩展包下载:

 PhalApi-Library 扩展库中下载获取 Auth 扩展包,如使用:

git clone https://git.oschina.net/dogstar/PhalApi-Library.git

然后把 Auth 目录复制到 ./PhalApi/Library/ 下,即:

cp ./PhalApi-Library/Auth ./PhalApi/Library/ -R

(2)、数据库表导入:

要使用Auth扩展,必须先导入相关的数据表,需要导入以下表:

$ cd /Library/User
$ tree

├── Data
│   ├── auth_group.sql
│   ├── auth_rule.sql
│   ├── auth_group_access.sql

导入前,可以自行调整表的前缀。

特别注意: 要实现Auth权限认证,数据库中必须存在User表,用于存放用户信息,但User表是根据项目需求自主创建的,只要存在ID主键即可。

(3)、项目配置:

将 PhalApi-Library/Auth/Config/app.php 里面的配置拷贝到你的项目配置:

return array(
    //请将以下配置拷贝到 ./Config/app.php 文件对应的位置中
    'auth' => array(
        'auth_on' => true, // 认证开关
        'auth_user' => 'user', // 用户信息表,
        'auth_group' => 'auth_group', // 组数据表名
        'auth_group_access' => 'auth_group_access', // 用户-组关系表
        'auth_rule' => 'auth_rule', // 权限规则表
        'auth_not_check_user' => array(1) //跳过权限检测的用户
    )
);

(4)、入口注册:

//必须显式注册,以便可以让服务自行初始化
DI()->authLite = new Auth_Lite();

入门使用

经过前面的一番配置,马上就可以实现权限认证功能了。

(1)、用户登录

Auth是基于用户和组的认证方式,所以在认证之前,首先要实现用户登录,登录成功后,接口访问地址必须带上UserID参数,
至于登录过程由各位同学自行实现,此处不做描述。

(2)、权限检测

Auth权限认证使用非常简单,权限检测操作建议放在接口自定义签名认证的函数里面的,示例如下:

//$ vim ./Demo/Common/SignFilter.php 
<?php

class Common_SignFilter implements PhalApi_Filter
{
    public function check()
    {
        $user->checkLogin() //检测登录,自主实现

        $api=DI()->request->get('service','Default.Index'); //获取当前访问的接口
        $userId=DI()->request->get('user_id',0);//获取用户id参数
        $r=DI()->authLite->check($api,$userId);
        if(!$r){
            //抛出异常
        }
    }
}

给项目增加了权限检测的代码之后,访问接口,通常会抛出异常:

//访问地址
127.0.0.1/PhalApi/Public/Dome/&user_id=1;
//异常
{code:401,data:null,msg:"没有接口访问权限"}

此时抛出的异常是正常的,因为数据表里面并没有定义相关的规则,也没有创建相关的组和关联,所以下面的操作,才是关键。

(3)、数据库操作:

(3.1)创建组:

INSERT INTO `phalapi`.`phalapi_auth_group` (`id`, `title`, `status`, `rules`)
 VALUES (NULL, '超级管理员', '1', '');

输入图片说明

(3.2)用户与组关联:

INSERT INTO `phalapi`.`phalapi_auth_group_access` (`uid`, `group_id`) VALUES ('1', '1');

输入图片说明

注意: 一个用户可以关联多个组

(3.3)创建规则:

INSERT INTO `phalapi`.`phalapi_auth_rule` (`id`, `name`, `title`, `status`, `add_condition`) VALUES (NULL, 'Default.Index', '默认接口', '1', ''); 

输入图片说明

对于规则,需要做一下说明,通常做权限认证就是对访问Url的认证,

RBAC的权限认证方式,是通过在数据库建立节点,模块/控制器/方法,然后在检测的时候获取url里面的指定参数,如:M=dome&a=Default&c=Index,跟数据库的数据做对比,如果节点存在,则通过认证,

Auth的规则实现更加简单,直接在规则表的name字段加入接口地址“Default.Index”即可,name字段存储的正是url的service参数。

(3.4)组关联规则:

UPDATE `phalapi`.`phalapi_auth_group` SET `rules` = '1' WHERE `phalapi_auth_group`.`id` = 1;

输入图片说明
更新组表的rules字段,将规则id加入该字段。

(3.5)完成

经过上面的数据库操作之后,再访问刚才的连接,就不会抛出异常了,如果访问别的接口,还是会抛出异常,下面要做的就是往数据库里不断更新规则了,
当然,如果所有的操作都要想上面去操作数据库的话,肯定是不合理的,所以Auth扩展也提供了,所有操作的Api接口:

$ cd /Library/Auth
$ tree

├── Auth
│   ├── Api
│   │    ├──Group.php
│   │    ├──Rule.php
│   ├── Domain
│   ├── Model

当然,您也可以自己编写接口来实现这些功能。

其他说明

(1)、免检用户

如果您需要保留一个或多个用户可以不经过权限检测,可以访问所有接口,您可以在配置中加入免检用户ID:

'auth_not_check_user' => array(1,2) //跳过权限检测的用户

swoole支持下的长链接和异步任务实现
基于FastRoute的快速路由(支持RESTful)
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

八、视频教程

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }