文章目录
1.权限的作用
使用者角度
- 权力 和 限制
- 正确的行使权力
- 在限制范围内使用权力
设计者角度
- 安全:控制不同的角色合理的访问不同的资源
2.权限模型介绍
ACL和RBAC对比
RBAC优势
- 简化了用户和权限的关系
- 易扩展,易维护
针对不同用户分配权限,ACL要操作多次,而RBAC只要针对角色分配就可以
3.RBAC架构
4.RBAC模块功能
5.实战案例
5.1数据库设计
user表
字段名 | 类型 | 备注 |
---|---|---|
id | int(11) | |
name | varchar(20) | 用户名 |
varchar(30) | 用户邮箱 | |
is_admin | tinyint(1) | 是否是管理员,1是管理员,默认值0 |
status | tinyint(1) | 状态,1表示有效,0表示无效 |
updated_time | timestamp | 更新时间 |
created_time | timestamp | 插入时间 |
role表
字段名 | 类型 | 备注 |
---|---|---|
id | int(11) | |
name | varchar(50) | 用户名 |
status | tinyint(1) | 状态,1表示有效,0表示无效 |
updated_time | timestamp | 更新时间 |
created_time | timestamp | 插入时间 |
user_role表
字段名 | 类型 | 备注 |
---|---|---|
id | int(11) | |
uid | int(11) | user_id |
role_id | int(11) | role_id |
created_time | timestamp | 插入时间 |
access表
字段名 | 类型 | 备注 |
---|---|---|
id | int(11) | |
title | varchar(50) | 权限标题 |
urls | varchar(1000) | 对应页面url |
status | tinyint(1) | 状态,1表示有效,0表示无效 |
updated_time | timestamp | 更新时间 |
created_time | timestamp | 插入时间 |
role_access表
字段名 | 类型 | 备注 |
---|---|---|
id | int(11) | |
role_id | int(11) | role_id |
access_id | int(11) | access_id |
created_time | timestamp | 插入时间 |
app_access_log表(用户操作记录表)
5.2框架配置(略),使用tp5
5.3bootstrap界面布局搭建
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>RBAC</title>
<link rel="stylesheet" href="__STATIC__/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="__STATIC__/bootstrap/css/app.css">
<script src="__STATIC__/bootstrap/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
</head>
<body>
<!--导航条-->
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="#">RBAC</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">首页</a></li>
</ul>
<p class="navbar-text navbar-right">Hi,xxx</p>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<!--菜单栏和内容区域-->
<div class="container-fluid">
<div class="col-sm-2 col-md-2 col-lg-2 sidebar">
<ul class="nav nav-sidebar">
<li>权限演示页面</li>
<li><a href="javascript:void(0);">测试一</a></li>
<li><a href="javascript:void(0);">测试二</a></li>
<li><a href="javascript:void(0);">测试三</a></li>
<li><a href="javascript:void(0);">测试四</a></li>
<li><a href="javascript:void(0);">测试五</a></li>
<li>系统设置</li>
<li><a href="javascript:void(0);">用户管理</a></li>
<li><a href="javascript:void(0);">角色管理</a></li>
<li><a href="javascript:void(0);">权限管理</a></li>
</ul>
</div>
<div class="col-sm-10 col-sm-offset-2 col-md-10 col-md-offset-2 col-lg-10 col-lg-offset-2">
<footer>
<p class="pull-left">@baicai</p>
<p class="pull-right">Power By baicai</p>
</footer>
</div>
</div>
</body>
</html>
定义一个url统一管理类
<?php
namespace app\common\controller;
use think\Controller;
class UrlService extends Controller
{
public static function buildUrl($uri, $params=[])
{
return url($uri,$params);
}
public static function buildNullUrl()
{
return "javascript:void(0);";
}
}
5.4伪登录功能
没有真实的登录,在实际的开发过程中,肯定是要用户输入用户名和密码,然后通过提交表单来实现登录,这个课程中就没有这一个过程,只是通过get传递uid参数来实现假的登录
建立模型
详细看github
//伪登录方法
public function vLogin()
{
$uid = request()->get('uid', 0);
if (!$uid) {
return $this->redirect('/');
}
$userInfo = \app\index\model\User::get($uid);
if (!$userInfo) {
return $this->redirect('/');
}
//cookie保存登录态,cookie值加密 约定一个规则 userAuthToken + "#" + uid
$this->createLoginStatus($userInfo);
return $this->redirect('index/index');
}
//验证登录是否有效,返回 true or false
protected function checkLoginStatus()
{
$authCookie = cookie($this->authCookieName);
if (!$authCookie) {
return false;
}
list($authCookie, $uid) = explode("#", $authCookie);
if (!$authCookie || !$uid) {
return false;
}
if ($uid && preg_match("/^\d+$/", $uid)) {
$userInfo = \app\index\model\User::get($uid);
if (!$userInfo) {
return false;
}
//校验码
if ($authCookie != $this->createAuthToken($userInfo['id'], $userInfo['name'], $userInfo['email'], $_SERVER['HTTP_USER_AGENT'])) {
return false;
}
$this->currentUser = $userInfo;
$this->assign('currentuser', $userInfo);
return true;
}
return false;
}