模型管理和权限管理
阅读本小节前,请确保你一定完成了快速开始的全部内容 本小结使用
postman
作为 http 测试工具,请确保你有 postman 或类似的 http 测试工具,它是我们后续开发必不可少的工具。
架构介绍
Lin 的定位是一整套的 ThinkPHP TP5 CMS 解决方案。对于任何的 CMS 来说,权限这一块都是不可或缺的,因此 Lin 在基础框架中便已经集成了权限模块,它是开箱即用的。
不过 Lin 的权限模块的概念可能与其它的权限框架由些许不同,当然你完全不用担心,因为大部分权限系统的模式都大同小异。
在 Lin 的权限模块中,我们有三个模型类来组成这个这个权限模块。如下:
用户模型(LinUser,数据表名称为 lin_user) 用户是权限系统服务的基本单位,CMS 与一些网站的很大的区别在于,CMS 可能不存在不用登陆便可进入的页面(登陆页除外)。
简而言之,用户是必须的。在源代码model/LinUser.php
可以找到LinUser
这个类。LinUser类实则是一个数据库模型类,它有一些必要的属性和实用的方法。
权限组模型(LinGroup,数据表名称为 lin_group) 权限组是一个非常重要的概念,权限组是权限分配的基本单位,同时它也是容纳用户的容器,它是用户与权限之间的纽带。
一个用户只能属于一个权限组,超级管理员(super)不属于任何权限组,但超级管理员拥有所有的权限,一个权限组可以拥有多个用户。
权限组也可拥有多个权限,也就是说,在某个权限组的用户拥有该权限组的所有权限。
如果,你还不清楚,请你在源代码model/LinGroup.php
中阅读LinGroup
这个类的属性。
权限模型(auth_model,数据表名称为 lin-auth) 你可以把一个权限理解成一把钥匙,然你拥有这把钥匙的时候你就可以打开某扇门,而当你没有这把钥匙的时候,你就会被锁在门的外面。
所以对于某个用户,比如说:你,当你拥有某个权限时,你就可以访问某个 API(或多个 API),而当你没有这个权限时,你访问 API 时会得到一个授权失败或禁止的信息。
想了解更详细的细节,请查看源代码model/LinAuth
中LinAuth`这个类。
上述中的源代码,请在第三方包lin-cms-tp5中寻找。
基本使用
要实现权限控制,需要两个步骤,分别是给控制器方法添加权限注解、挂载控制类到
权限图(lib\auth\AuthMap.php)
中,下面演示如何使用
- 控制器方法
/**
* @auth('创建用户','管理员','hidden')
* @param Request $request
*/
public function register(Request $request)
{
(new RegisterForm())->goCheck();
$params = $request->post();
LinUser::createUser($params);
logger('创建了一个用户');
return writeJson(201, '', '用户创建成功');
}
这里我们创建了一个控制器方法,用来创建一个后台账户,我们需要给这个方法添加一个访问权限,权限名称叫创建用户
,属于管理员
权限模块,于是我们在方法的注释中加入@auth('创建用户','管理员','hidden')
这一段内容,这样我就为这个方法标识好权限了,这里hidden
的作用就是让这个权限信息不会出现在前端查询所有可分配权限时出现,示例代码中我们将所有管理员模块的权限都添加了hidden
。
接着我们需要把这个整个控制器类挂载到权限图
中去。(暂时叫这个名字)
- 权限图(AuthMap.php)
打开项目根目录下的
lib/auth/AuthMap.php
class AuthMap
{
private $authList;
public function __construct()
{
$this->authList = [
'app\api\controller\cms\User',
'app\api\controller\cms\Admin',
'app\api\controller\cms\Log',
'app\api\controller\v1\Book',
];
}
AuthMap
类会有一个$authList属性,它是一个数组,如果一个控制器类下面存在需要权限控制的方法,那就把这个类添加在数组中去。这样前端在调用查询所有可分配权限的时候,AuthMap
类就会去扫描解析所有已挂载类下面所有方法中的@auth
注释信息然后生成数据。
- 权限校验中间件
中间件文件所在路径
/application/http/middleware/Auth.php
,可阅读中间件源码查看实现逻辑和流程;该中间件在项目根目录/route/route.php
中进行了挂载。
Route::group('', function () {
Route::group('cms', function () {
// 省略代码
})
Route::group('v1', function () {
// 省略代码
})
})->middleware(['Auth','ReflexValidate'])->allowCrossDomain();#挂载权限校验中间件auth到路由分组的根节点,根节点下的嵌套分组都会应用。
权限的名称和所属模块是可以自由定义的,但要注意因为lin-cms是前后端分离的项目,你在后端为控制器方法定义的权限内容必须是和你前端定义的权限名称相匹配这样菜单才会正常渲染。另外,管理员模块即便不添加hidden并分配给了分组,前端也不会显示对应菜单。