ThinkPHP 6.1企业级RBAC权限系统开发实战:从零构建安全后台管理系统

2025-11-05 0 250

前言:企业级权限管理的重要性

在现代企业应用开发中,权限管理是保障系统安全的核心环节。基于角色的访问控制(RBAC)模型通过角色和权限的灵活配置,为企业提供了一套完善的安全管理方案。本文将基于ThinkPHP 6.1框架,从零开始构建一个完整的企业级RBAC权限系统

一、RBAC权限模型设计原理

1.1 核心概念解析

RBAC(Role-Based Access Control)模型包含四个核心元素:用户(User)、角色(Role)、权限(Permission)和操作(Operation)。通过用户-角色-权限的层级关系,实现灵活的权限控制。

1.2 数据库表结构设计

-- 用户表
CREATE TABLE `admin_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(255) NOT NULL COMMENT '密码',
  `realname` varchar(50) 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 `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 角色表
CREATE TABLE `admin_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL COMMENT '角色名称',
  `description` varchar(255) DEFAULT NULL COMMENT '角色描述',
  `status` tinyint(1) DEFAULT '1' COMMENT '状态:1正常 0禁用',
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 权限表
CREATE TABLE `admin_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL COMMENT '权限名称',
  `path` varchar(255) NOT NULL COMMENT '权限路径',
  `method` varchar(10) DEFAULT 'GET' COMMENT '请求方法',
  `type` tinyint(1) DEFAULT '1' COMMENT '权限类型:1菜单 2按钮 3接口',
  `parent_id` int(11) DEFAULT '0' COMMENT '父级权限ID',
  `sort` int(11) DEFAULT '0' COMMENT '排序',
  `icon` varchar(50) DEFAULT NULL COMMENT '图标',
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 用户角色关联表
CREATE TABLE `admin_user_role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `role_id` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 角色权限关联表
CREATE TABLE `admin_role_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `role_id` int(11) NOT NULL,
  `permission_id` int(11) NOT NULL,
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `role_id` (`role_id`),
  KEY `permission_id` (`permission_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

二、ThinkPHP 6.1项目初始化与配置

2.1 项目创建与扩展安装

# 创建ThinkPHP项目
composer create-project topthink/think tp6-rbac

# 安装验证码扩展
composer require topthink/think-captcha

# 安装JWT扩展
composer require firebase/php-jwt

2.2 数据库配置

// config/database.php
return [
    // 默认数据库连接
    'default' => 'mysql',
    
    // 数据库连接信息
    'connections' => [
        'mysql' => [
            'type' => 'mysql',
            'hostname' => '127.0.0.1',
            'database' => 'tp6_rbac',
            'username' => 'root',
            'password' => '',
            'hostport' => '3306',
            'charset' => 'utf8mb4',
            'prefix' => 'admin_',
            'debug' => true,
        ]
    ]
];

2.3 模型层设计

// app/model/AdminUser.php
<?php
namespace appmodel;

use thinkModel;
use thinkmodelconcernSoftDelete;

class AdminUser extends Model
{
    use SoftDelete;
    
    protected $name = 'admin_user';
    protected $autoWriteTimestamp = true;
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    protected $deleteTime = 'delete_time';
    protected $hidden = ['password', 'delete_time'];
    
    // 用户角色关联
    public function roles()
    {
        return $this->belongsToMany(AdminRole::class, 'admin_user_role', 'role_id', 'user_id');
    }
    
    // 密码加密
    public function setPasswordAttr($value)
    {
        return password_hash($value, PASSWORD_DEFAULT);
    }
    
    // 验证密码
    public function verifyPassword($password)
    {
        return password_verify($password, $this->password);
    }
}

// app/model/AdminRole.php
<?php
namespace appmodel;

use thinkModel;

class AdminRole extends Model
{
    protected $name = 'admin_role';
    protected $autoWriteTimestamp = true;
    protected $createTime = 'create_time';
    
    // 角色权限关联
    public function permissions()
    {
        return $this->belongsToMany(AdminPermission::class, 'admin_role_permission', 'permission_id', 'role_id');
    }
    
    // 角色用户关联
    public function users()
    {
        return $this->belongsToMany(AdminUser::class, 'admin_user_role', 'user_id', 'role_id');
    }
}

// app/model/AdminPermission.php
<?php
namespace appmodel;

use thinkModel;

class AdminPermission extends Model
{
    protected $name = 'admin_permission';
    protected $autoWriteTimestamp = true;
    protected $createTime = 'create_time';
    
    // 权限角色关联
    public function roles()
    {
        return $this->belongsToMany(AdminRole::class, 'admin_role_permission', 'role_id', 'permission_id');
    }
    
    // 获取树形权限结构
    public static function getTree($parentId = 0)
    {
        $permissions = self::where('parent_id', $parentId)
            ->order('sort', 'desc')
            ->select();
            
        foreach ($permissions as $permission) {
            $permission->children = self::getTree($permission->id);
        }
        
        return $permissions;
    }
}

三、核心权限验证中间件开发

3.1 JWT令牌管理类

// app/common/JwtAuth.php
<?php
namespace appcommon;

use FirebaseJWTJWT;
use FirebaseJWTKey;
use thinkfacadeRequest;

class JwtAuth
{
    private static $secretKey = 'your-secret-key-here';
    private static $algorithm = 'HS256';
    
    // 生成令牌
    public static function generateToken($userId, $username)
    {
        $payload = [
            'iss' => 'tp6-rbac', // 签发者
            'iat' => time(), // 签发时间
            'exp' => time() + 7200, // 过期时间2小时
            'user_id' => $userId,
            'username' => $username
        ];
        
        return JWT::encode($payload, self::$secretKey, self::$algorithm);
    }
    
    // 验证令牌
    public static function verifyToken($token)
    {
        try {
            $decoded = JWT::decode($token, new Key(self::$secretKey, self::$algorithm));
            return (array)$decoded;
        } catch (Exception $e) {
            return false;
        }
    }
    
    // 从请求头获取令牌
    public static function getTokenFromHeader()
    {
        $authorization = Request::header('authorization');
        if ($authorization && preg_match('/Bearers+(.*)$/i', $authorization, $matches)) {
            return $matches[1];
        }
        return null;
    }
}

3.2 权限验证中间件

// app/middleware/AuthMiddleware.php
<?php
namespace appmiddleware;

use appcommonJwtAuth;
use appmodelAdminUser;
use thinkfacadeRequest;

class AuthMiddleware
{
    public function handle($request, Closure $next)
    {
        // 获取令牌
        $token = JwtAuth::getTokenFromHeader();
        
        if (!$token) {
            return json([
                'code' => 401,
                'message' => '未提供访问令牌',
                'data' => null
            ]);
        }
        
        // 验证令牌
        $payload = JwtAuth::verifyToken($token);
        if (!$payload) {
            return json([
                'code' => 401,
                'message' => '令牌无效或已过期',
                'data' => null
            ]);
        }
        
        // 获取用户信息
        $user = AdminUser::find($payload['user_id']);
        if (!$user || $user->status != 1) {
            return json([
                'code' => 401,
                'message' => '用户不存在或已被禁用',
                'data' => null
            ]);
        }
        
        // 将用户信息存储到请求对象
        $request->user = $user;
        $request->user_id = $user->id;
        
        return $next($request);
    }
}

3.3 权限检查中间件

// app/middleware/PermissionMiddleware.php
<?php
namespace appmiddleware;

use thinkfacadeRequest;

class PermissionMiddleware
{
    public function handle($request, Closure $next)
    {
        $user = $request->user;
        $currentPath = Request::pathinfo();
        $method = Request::method();
        
        // 超级管理员拥有所有权限
        if ($user->id == 1) {
            return $next($request);
        }
        
        // 检查用户权限
        $hasPermission = $this->checkUserPermission($user->id, $currentPath, $method);
        
        if (!$hasPermission) {
            return json([
                'code' => 403,
                'message' => '没有访问权限',
                'data' => null
            ]);
        }
        
        return $next($request);
    }
    
    private function checkUserPermission($userId, $path, $method)
    {
        // 查询用户的所有权限
        $permissions = AdminUser::with(['roles.permissions'])
            ->where('id', $userId)
            ->find()
            ->toArray();
            
        $userPermissions = [];
        foreach ($permissions['roles'] as $role) {
            foreach ($role['permissions'] as $permission) {
                $userPermissions[] = [
                    'path' => $permission['path'],
                    'method' => $permission['method']
                ];
            }
        }
        
        // 检查当前请求是否在权限列表中
        foreach ($userPermissions as $permission) {
            if ($this->matchPermission($permission, $path, $method)) {
                return true;
            }
        }
        
        return false;
    }
    
    private function matchPermission($permission, $path, $method)
    {
        // 简单的路径匹配,实际项目中可以使用更复杂的路由匹配逻辑
        $permissionPath = trim($permission['path'], '/');
        $requestPath = trim($path, '/');
        
        return $permissionPath === $requestPath && 
               strtoupper($permission['method']) === strtoupper($method);
    }
}

四、控制器与业务逻辑实现

4.1 用户认证控制器

// app/controller/Auth.php
<?php
namespace appcontroller;

use appBaseController;
use appcommonJwtAuth;
use appmodelAdminUser;
use thinkfacadeRequest;
use thinkfacadeValidate;

class Auth extends BaseController
{
    // 用户登录
    public function login()
    {
        $data = Request::only(['username', 'password', 'captcha']);
        
        // 数据验证
        $validate = Validate::rule([
            'username|用户名' => 'require|length:3,20',
            'password|密码' => 'require|length:6,20',
            'captcha|验证码' => 'require|captcha'
        ]);
        
        if (!$validate->check($data)) {
            return json([
                'code' => 400,
                'message' => $validate->getError(),
                'data' => null
            ]);
        }
        
        // 验证用户
        $user = AdminUser::where('username', $data['username'])->find();
        if (!$user || !$user->verifyPassword($data['password'])) {
            return json([
                'code' => 400,
                'message' => '用户名或密码错误',
                'data' => null
            ]);
        }
        
        if ($user->status != 1) {
            return json([
                'code' => 400,
                'message' => '账户已被禁用',
                'data' => null
            ]);
        }
        
        // 生成令牌
        $token = JwtAuth::generateToken($user->id, $user->username);
        
        // 更新最后登录时间
        $user->save(['last_login_time' => date('Y-m-d H:i:s')]);
        
        return json([
            'code' => 200,
            'message' => '登录成功',
            'data' => [
                'token' => $token,
                'user_info' => [
                    'id' => $user->id,
                    'username' => $user->username,
                    'realname' => $user->realname
                ]
            ]
        ]);
    }
    
    // 获取当前用户信息
    public function userInfo()
    {
        $user = Request::user;
        
        // 获取用户权限菜单
        $menus = $this->getUserMenus($user->id);
        
        return json([
            'code' => 200,
            'message' => 'success',
            'data' => [
                'user_info' => $user->visible(['id', 'username', 'realname'])->toArray(),
                'menus' => $menus
            ]
        ]);
    }
    
    // 获取用户菜单
    private function getUserMenus($userId)
    {
        $user = AdminUser::with(['roles.permissions' => function($query) {
            $query->where('type', 1)->order('sort', 'desc');
        }])->where('id', $userId)->find();
        
        $menus = [];
        foreach ($user->roles as $role) {
            foreach ($role->permissions as $permission) {
                $menus[$permission->id] = $permission->toArray();
            }
        }
        
        return $this->buildMenuTree(array_values($menus));
    }
    
    // 构建菜单树
    private function buildMenuTree($menus, $parentId = 0)
    {
        $tree = [];
        foreach ($menus as $menu) {
            if ($menu['parent_id'] == $parentId) {
                $children = $this->buildMenuTree($menus, $menu['id']);
                if ($children) {
                    $menu['children'] = $children;
                }
                $tree[] = $menu;
            }
        }
        return $tree;
    }
}

4.2 用户管理控制器

// app/controller/User.php
<?php
namespace appcontroller;

use appBaseController;
use appmodelAdminUser;
use appmodelAdminRole;
use thinkfacadeRequest;

class User extends BaseController
{
    // 用户列表
    public function index()
    {
        $page = Request::param('page', 1);
        $limit = Request::param('limit', 10);
        $keyword = Request::param('keyword', '');
        
        $query = AdminUser::with('roles');
        
        if ($keyword) {
            $query->whereLike('username|realname', "%{$keyword}%");
        }
        
        $list = $query->paginate([
            'page' => $page,
            'list_rows' => $limit
        ]);
        
        return json([
            'code' => 200,
            'message' => 'success',
            'data' => $list
        ]);
    }
    
    // 创建用户
    public function create()
    {
        $data = Request::only(['username', 'password', 'realname', 'role_ids']);
        
        // 验证用户名是否已存在
        $exists = AdminUser::where('username', $data['username'])->find();
        if ($exists) {
            return json([
                'code' => 400,
                'message' => '用户名已存在',
                'data' => null
            ]);
        }
        
        // 创建用户
        $user = AdminUser::create($data);
        
        // 分配角色
        if (!empty($data['role_ids'])) {
            $user->roles()->saveAll($data['role_ids']);
        }
        
        return json([
            'code' => 200,
            'message' => '用户创建成功',
            'data' => null
        ]);
    }
    
    // 更新用户
    public function update($id)
    {
        $data = Request::only(['realname', 'status', 'role_ids']);
        
        $user = AdminUser::find($id);
        if (!$user) {
            return json([
                'code' => 404,
                'message' => '用户不存在',
                'data' => null
            ]);
        }
        
        // 更新用户信息
        $user->save($data);
        
        // 更新角色
        if (isset($data['role_ids'])) {
            $user->roles()->detach();
            if (!empty($data['role_ids'])) {
                $user->roles()->saveAll($data['role_ids']);
            }
        }
        
        return json([
            'code' => 200,
            'message' => '用户更新成功',
            'data' => null
        ]);
    }
}

五、路由配置与中间件应用

5.1 路由配置文件

// route/app.php
<?php
use thinkfacadeRoute;

// 认证相关路由
Route::group('auth', function() {
    Route::post('login', 'Auth/login');
    Route::get('userinfo', 'Auth/userInfo');
});

// 需要认证的路由组
Route::group(function() {
    // 用户管理
    Route::group('user', function() {
        Route::get('/', 'User/index');
        Route::post('/', 'User/create');
        Route::put(':id', 'User/update');
        Route::delete(':id', 'User/delete');
    });
    
    // 角色管理
    Route::group('role', function() {
        Route::get('/', 'Role/index');
        Route::post('/', 'Role/create');
        Route::put(':id', 'Role/update');
        Route::get('permissions/:id', 'Role/getPermissions');
        Route::post('permissions/:id', 'Role/setPermissions');
    });
    
    // 权限管理
    Route::group('permission', function() {
        Route::get('/', 'Permission/index');
        Route::get('tree', 'Permission/tree');
        Route::post('/', 'Permission/create');
        Route::put(':id', 'Permission/update');
    });
})->middleware([appmiddlewareAuthMiddleware::class, appmiddlewarePermissionMiddleware::class]);

六、系统测试与安全优化

6.1 功能测试用例

// 登录测试
POST /auth/login
{
    "username": "admin",
    "password": "123456",
    "captcha": "abcd"
}

// 获取用户信息测试
GET /auth/userinfo
Headers: Authorization: Bearer {token}

// 用户列表测试
GET /user?page=1&limit=10
Headers: Authorization: Bearer {token}

6.2 安全优化措施

  • 密码安全:使用password_hash进行强加密
  • 令牌管理:JWT令牌设置合理过期时间
  • SQL注入防护:使用ThinkPHP的ORM防止SQL注入
  • XSS防护:输出数据进行HTML转义
  • CSRF防护:启用ThinkPHP的CSRF保护中间件
  • 请求限流:对API接口进行访问频率限制

6.3 性能优化建议

  • 使用Redis缓存用户权限数据
  • 对频繁查询的权限数据进行缓存
  • 使用数据库连接池提高并发性能
  • 对权限检查结果进行缓存,避免重复查询

七、部署与扩展方案

7.1 生产环境部署

# 关闭调试模式
// .env
APP_DEBUG = false

# 配置缓存
php think optimize:route
php think optimize:config

# 设置目录权限
chmod -R 755 runtime
chmod -R 755 public/uploads

7.2 系统扩展方案

基于当前RBAC系统,可以进一步扩展以下功能:

  • 操作日志:记录用户操作行为
  • 数据权限:基于组织架构的数据访问控制
  • 多租户:支持多租户的SaaS系统
  • API网关:集成API网关进行统一权限管理
  • 单点登录:实现多系统间的单点登录

结语

本文详细介绍了基于ThinkPHP 6.1构建企业级RBAC权限管理系统的完整流程,从数据库设计、模型构建、中间件开发到控制器实现,涵盖了权限系统的所有核心环节。通过本系统的实现,不仅能够满足企业基本的权限管理需求,还提供了良好的扩展性和安全性。

在实际项目开发中,建议根据具体业务需求对系统进行定制化调整,同时结合缓存、日志、监控等辅助系统,构建更加完善的企业级应用架构。

ThinkPHP 6.1企业级RBAC权限系统开发实战:从零构建安全后台管理系统
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 thinkphp ThinkPHP 6.1企业级RBAC权限系统开发实战:从零构建安全后台管理系统 https://www.taomawang.com/server/thinkphp/1380.html

下一篇:

已经没有下一篇了!

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务