本文目录导读:

我来为您设计一个完整的ThinkPHP用户权限RBAC系统。
数据库设计
数据表结构
-- 用户表 CREATE TABLE `tp_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(255) NOT NULL COMMENT '密码', `real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名', `email` varchar(100) DEFAULT NULL COMMENT '邮箱', `phone` varchar(20) DEFAULT NULL COMMENT '手机号', `status` tinyint(1) DEFAULT '1' COMMENT '状态:1启用 0禁用', `last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间', `last_login_ip` varchar(50) DEFAULT NULL COMMENT '最后登录IP', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; -- 角色表 CREATE TABLE `tp_role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '角色名称', `code` varchar(50) NOT NULL COMMENT '角色标识', `description` varchar(255) DEFAULT NULL COMMENT '角色描述', `status` tinyint(1) DEFAULT '1' COMMENT '状态:1启用 0禁用', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `code` (`code`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表'; -- 权限表(菜单/节点) CREATE TABLE `tp_permission` ( `id` int(11) NOT NULL AUTO_INCREMENT, `parent_id` int(11) DEFAULT '0' COMMENT '父权限ID', `name` varchar(50) NOT NULL COMMENT '权限名称', `type` tinyint(1) DEFAULT '1' COMMENT '类型:1菜单 2按钮 3API', `url` varchar(255) DEFAULT NULL COMMENT '路由地址', `icon` varchar(50) DEFAULT NULL COMMENT '图标', `sort` int(11) DEFAULT '0' COMMENT '排序', `status` tinyint(1) DEFAULT '1' COMMENT '状态:1启用 0禁用', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='权限表'; -- 用户角色关联表 CREATE TABLE `tp_user_role` ( `user_id` int(11) NOT NULL, `role_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色关联表'; -- 角色权限关联表 CREATE TABLE `tp_role_permission` ( `role_id` int(11) NOT NULL, `permission_id` int(11) NOT NULL, PRIMARY KEY (`role_id`,`permission_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色权限关联表';
模型创建
用户模型
<?php
// app/model/User.php
namespace app\model;
use think\Model;
use think\model\concern\SoftDelete;
class User extends Model
{
use SoftDelete;
protected $deleteTime = 'delete_time';
// 关联角色
public function roles()
{
return $this->belongsToMany(Role::class, 'user_role', 'role_id', 'user_id');
}
// 密码加密
public function setPasswordAttr($value)
{
return password_hash($value, PASSWORD_BCRYPT);
}
// 验证密码
public function verifyPassword($password)
{
return password_verify($password, $this->password);
}
// 获取用户所有权限
public function getPermissions()
{
$permissionIds = [];
$roles = $this->roles()->where('status', 1)->select();
foreach ($roles as $role) {
$permissions = $role->permissions()->where('status', 1)->select();
foreach ($permissions as $permission) {
$permissionIds[$permission->url] = true;
}
}
return array_keys($permissionIds);
}
// 检查权限
public function hasPermission($permissionUrl)
{
$permissions = $this->getPermissions();
return in_array($permissionUrl, $permissions);
}
// 检查角色
public function hasRole($roleCode)
{
$roles = $this->roles()->where('code', $roleCode)->find();
return $roles ? true : false;
}
}
角色模型
<?php
// app/model/Role.php
namespace app\model;
use think\Model;
use think\model\concern\SoftDelete;
class Role extends Model
{
use SoftDelete;
// 关联用户
public function users()
{
return $this->belongsToMany(User::class, 'user_role', 'user_id', 'role_id');
}
// 关联权限
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'permission_id', 'role_id');
}
// 添加角色并绑定用户
public static function createRole($data, $userIds = [])
{
$role = self::create($data);
if (!empty($userIds)) {
$role->users()->attach($userIds);
}
return $role;
}
}
权限模型
<?php
// app/model/Permission.php
namespace app\model;
use think\Model;
class Permission extends Model
{
// 关联角色
public function roles()
{
return $this->belongsToMany(Role::class, 'role_permission', 'role_id', 'permission_id');
}
// 获取树形权限
public static function getTree($parentId = 0)
{
$permissions = self::where('parent_id', $parentId)
->order('sort', 'asc')
->select()
->toArray();
foreach ($permissions as &$permission) {
$children = self::getTree($permission['id']);
if (!empty($children)) {
$permission['children'] = $children;
}
}
return $permissions;
}
}
中间件实现
<?php
// app/middleware/AuthCheck.php
namespace app\middleware;
use think\facade\Session;
use think\facade\Url;
class AuthCheck
{
public function handle($request, \Closure $next)
{
// 检查是否登录
if (!Session::has('user_id')) {
if ($request->isAjax()) {
return json(['code' => 401, 'msg' => '请先登录']);
}
return redirect((string)Url::build('login/index'));
}
// 获取当前请求的模块、控制器、方法
$module = app('http')->getName();
$controller = $request->controller();
$action = $request->action();
// 构建权限标识
$permission = "{$module}/{$controller}/{$action}";
// 超级管理员跳过验证
$user = \app\model\User::find(Session::get('user_id'));
if ($user->hasRole('admin')) {
return $next($request);
}
// 检查权限
if (!$user->hasPermission($permission)) {
if ($request->isAjax()) {
return json(['code' => 403, 'msg' => '没有权限']);
}
abort(403, '没有访问权限');
}
return $next($request);
}
}
认证服务类
<?php
// app/service/AuthService.php
namespace app\service;
use app\model\User;
use app\model\Role;
use app\model\Permission;
use think\facade\Session;
use think\facade\Cache;
class AuthService
{
/**
* 登录认证
*/
public function login($username, $password)
{
$user = User::where('username', $username)
->where('status', 1)
->find();
if (!$user) {
return ['code' => 0, 'msg' => '用户不存在或已被禁用'];
}
if (!$user->verifyPassword($password)) {
return ['code' => 0, 'msg' => '密码错误'];
}
// 更新登录信息
$user->last_login_time = date('Y-m-d H:i:s');
$user->last_login_ip = request()->ip();
$user->save();
// 设置Session
Session::set('user_id', $user->id);
Session::set('user_info', $user->toArray());
// 缓存权限
$this->cacheUserPermissions($user->id);
return ['code' => 1, 'msg' => '登录成功', 'user' => $user];
}
/**
* 缓存用户权限
*/
public function cacheUserPermissions($userId)
{
$user = User::find($userId);
$permissions = $user->getPermissions();
Cache::set("user_permissions_{$userId}", $permissions, 120);
return $permissions;
}
/**
* 退出登录
*/
public function logout()
{
$userId = Session::get('user_id');
Cache::delete("user_permissions_{$userId}");
Session::clear();
}
/**
* 获取当前用户信息
*/
public function getUserInfo()
{
$userId = Session::get('user_id');
if (!$userId) {
return null;
}
$user = User::with(['roles'])
->find($userId);
return $user;
}
/**
* 生成权限树
*/
public function getPermissionTree()
{
$user = $this->getUserInfo();
if (!$user) {
return [];
}
// 超级管理员获取所有权限
if ($user->hasRole('admin')) {
$permissions = Permission::where('type', 1)
->order('sort', 'asc')
->select()
->toArray();
} else {
// 普通用户获取自己的权限菜单
$roleIds = $user->roles()->column('id');
$permissionIds = \think\facade\Db::name('role_permission')
->whereIn('role_id', $roleIds)
->column('permission_id');
$permissions = Permission::whereIn('id', $permissionIds)
->where('type', 1)
->where('status', 1)
->order('sort', 'asc')
->select()
->toArray();
}
return $this->buildTree($permissions);
}
/**
* 构建树形结构
*/
private function buildTree($data, $parentId = 0)
{
$tree = [];
foreach ($data as $item) {
if ($item['parent_id'] == $parentId) {
$children = $this->buildTree($data, $item['id']);
if ($children) {
$item['children'] = $children;
}
$tree[] = $item;
}
}
return $tree;
}
}
控制器示例
<?php
// app/controller/Login.php
namespace app\controller;
use think\Request;
use app\service\AuthService;
class Login
{
protected $authService;
public function __construct(AuthService $authService)
{
$this->authService = $authService;
}
// 显示登录页面
public function index()
{
return view('login/index');
}
// 处理登录
public function login(Request $request)
{
$username = $request->post('username');
$password = $request->post('password');
$result = $this->authService->login($username, $password);
if ($result['code'] == 1) {
return json(['code' => 1, 'msg' => '登录成功', 'url' => '/index']);
}
return json(['code' => 0, 'msg' => $result['msg']]);
}
// 退出登录
public function logout()
{
$this->authService->logout();
return redirect('/login');
}
}
<?php
// app/controller/User.php
namespace app\controller;
use app\model\User;
use app\model\Role;
use think\Request;
class User extends Base
{
// 用户列表
public function index()
{
$users = User::with('roles')->paginate(10);
return view('user/index', ['users' => $users]);
}
// 添加用户
public function add()
{
if (request()->isPost()) {
$data = request()->post();
$roles = $data['roles'] ?? [];
unset($data['roles']);
$user = User::create($data);
if (!empty($roles)) {
$user->roles()->attach($roles);
}
return json(['code' => 1, 'msg' => '添加成功']);
}
$roles = Role::where('status', 1)->select();
return view('user/add', ['roles' => $roles]);
}
// 分配角色
public function assignRole($userId)
{
if (request()->isPost()) {
$roleIds = request()->post('roles', []);
$user = User::find($userId);
$user->roles()->detach();
if (!empty($roleIds)) {
$user->roles()->attach($roleIds);
}
// 清除权限缓存
\think\facade\Cache::delete("user_permissions_{$userId}");
return json(['code' => 1, 'msg' => '分配成功']);
}
$user = User::with('roles')->find($userId);
$roles = Role::where('status', 1)->select();
return view('user/assign_role', [
'user' => $user,
'roles' => $roles
]);
}
}
路由配置
<?php
// route/app.php
use think\facade\Route;
// 登录相关
Route::get('login', 'Login/index');
Route::post('login', 'Login/login');
Route::get('logout', 'Login/logout');
// 需要认证的路由
Route::group(function () {
// 首页
Route::get('/', 'Index/index');
Route::get('index', 'Index/index');
// 用户管理
Route::group('user', function () {
Route::get('/', 'User/index');
Route::get('add', 'User/add');
Route::post('add', 'User/add');
Route::get('edit/:id', 'User/edit');
Route::post('edit', 'User/edit');
Route::post('delete/:id', 'User/delete');
Route::get('assign/:id', 'User/assignRole');
Route::post('assign', 'User/assignRole');
});
// 角色管理
Route::group('role', function () {
Route::get('/', 'Role/index');
Route::get('add', 'Role/add');
Route::post('add', 'Role/add');
Route::post('delete/:id', 'Role/delete');
});
})->middleware(\app\middleware\AuthCheck::class);
视图模板示例
<!-- app/view/layout/main.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">{$title|default='管理系统'}</title>
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<div class="layout">
<div class="sidebar">
<ul>
{foreach $menus as $menu}
{if isset($menu['children'])}
<li class="has-sub">
<a href="javascript:;">{$menu.name}</a>
<ul>
{foreach $menu['children'] as $child}
<li><a href="{$child.url}">{$child.name}</a></li>
{/foreach}
</ul>
</li>
{else}
<li><a href="{$menu.url}">{$menu.name}</a></li>
{/if}
{/foreach}
</ul>
</div>
<div class="main">
{__CONTENT__}
</div>
</div>
</body>
</html>
初始化数据
<?php
// database/seed/RbacSeeder.php
namespace database\seed;
use think\Db;
class RbacSeeder
{
public function run()
{
// 创建超级管理员角色
$adminRoleId = Db::name('role')->insertGetId([
'name' => '超级管理员',
'code' => 'admin',
'description' => '拥有所有权限',
'status' => 1,
'create_time' => date('Y-m-d H:i:s')
]);
// 创建默认用户
$userId = Db::name('user')->insertGetId([
'username' => 'admin',
'password' => password_hash('123456', PASSWORD_BCRYPT),
'real_name' => '管理员',
'status' => 1,
'create_time' => date('Y-m-d H:i:s')
]);
// 绑定用户角色
Db::name('user_role')->insert([
'user_id' => $userId,
'role_id' => $adminRoleId
]);
// 创建权限数据
$permissions = [
['name' => '系统管理', 'parent_id' => 0, 'url' => '/system', 'sort' => 1],
['name' => '用户管理', 'parent_id' => 1, 'url' => '/user', 'sort' => 1],
['name' => '角色管理', 'parent_id' => 1, 'url' => '/role', 'sort' => 2],
['name' => '权限管理', 'parent_id' => 1, 'url' => '/permission', 'sort' => 3],
];
foreach ($permissions as $permission) {
$permissionId = Db::name('permission')->insertGetId($permission);
// 为超级管理员分配所有权限
Db::name('role_permission')->insert([
'role_id' => $adminRoleId,
'permission_id' => $permissionId
]);
}
}
}
扩展功能建议
- 多级权限控制: 支持菜单、按钮、API级别的权限控制
- 权限缓存: 使用Redis缓存用户权限,提高性能
- 操作日志: 记录用户关键操作日志
- 数据权限: 扩展实现数据级别的权限控制
- 登录限流: 防止暴力破解
- 单点登录: 同一账号仅允许一处登录
- 权限动态更新: 管理员修改权限后自动刷新所有用户缓存
安全建议
- 密码必须加密存储
- Token认证 + Session双机制
- CSRF防护
- SQL注入防护
- XSS攻击防护
- 访问频率限制
- 日志审计系统
这个RBAC系统设计完整,可以满足大部分中小型项目的权限管理需求,可以根据实际需求调整功能,比如增加数据权限、组织架构等。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播