SKILL.md 4.3 KB

功能权限控制系统实现技能

技能描述

实现一个完整的功能权限控制系统,包括后端权限验证和前端按钮控制。

系统架构

1. 数据模型

  • Sys_User: 用户表
  • Sys_Role: 角色表
  • Sys_FunctionCode: 功能代码表
  • Sys_User_Sys_Role: 用户角色关联表
  • Sys_Role_Sys_FunctionCode: 角色功能代码关联表

2. 认证服务实现(com.lianda.auth)

核心组件

  • 实体类:

    • SysUser, SysRole, SysFunctionCode
    • SysUserRole, SysRoleFunctionCode
    • UserRoleKey, RoleFunctionCodeKey
  • Repository层:

    • SysFunctionCodeRepository
    • SysUserRoleRepository
    • SysRoleFunctionCodeRepository
  • Service层:

    • UserPermissionService: 获取用户功能代码
    • UserPermissionServiceImpl: 实现PermissionService接口
  • 权限验证:

    • 在用户登录时获取用户的功能代码列表
    • 将功能代码列表添加到JWT Token中

JWT Token扩展

  • 登录时获取用户角色关联的功能代码
  • 将功能代码列表添加到JWT Token中
  • 前端和后端都可以从Token中解析权限信息

3. 后端服务实现(JavaBackend)

权限验证

  • RequirePermission注解: 标记需要权限的方法
  • PermissionInterceptor: 拦截器验证权限
  • CurrentUserUtil: 从JWT Token中解析用户权限

4. 前端实现

核心组件

  • 权限管理工具 (permission.js):

    • 解析JWT Token中的功能代码
    • 检查用户权限
    • 管理本地权限缓存
  • 权限指令 (permission.js):

    • Vue指令控制按钮显示
    • 根据权限动态显示/隐藏元素
  • Axios拦截器:

    • 响应拦截器提取功能代码
    • 更新本地权限缓存
    • 处理权限错误

使用方法

1. 后端使用

保护API端点

@RestController
@RequestMapping("/api/pilot-plan")
public class PilotPlanController {
    
    @GetMapping("/list")
    @RequirePermission("PILOT_PLAN_VIEW")  // 需要查看权限
    public ResponseEntity<PageResponse<PilotPlanDTO>> getPilotPlans(PilotPlanQueryDTO queryDTO) {
        // ...
    }
    
    @PostMapping("/import")
    @RequirePermission("PILOT_PLAN_IMPORT")  // 需要导入权限
    public ResponseEntity<Map<String, Object>> importPilotPlans(@RequestBody Map<String, Object> request) {
        // ...
    }
}

2. 前端使用

控制按钮显示

<template>
  <div>
    <!-- 只有拥有PILOT_PLAN_IMPORT权限的用户才能看到导入按钮 -->
    <el-button type="primary" @click="importData" v-permission="'PILOT_PLAN_IMPORT'">
      导入数据
    </el-button>
    
    <!-- 只有拥有PILOT_PLAN_EXPORT权限的用户才能看到导出按钮 -->
    <el-button type="success" @click="exportData" v-permission="'PILOT_PLAN_EXPORT'">
      导出数据
    </el-button>
  </div>
</template>

编程方式检查权限

import PermissionManager from '@/utils/permission.js'

// 检查用户是否有特定权限
if (PermissionManager.hasPermission('PILOT_PLAN_EDIT')) {
  // 用户有编辑权限,执行相应操作
  enableEditButtons();
} else {
  // 用户没有编辑权限,禁用相关功能
  disableEditButtons();
}

工作流程

  1. 用户登录 (在认证服务中):

    • 验证用户名密码
    • 查询用户的角色
    • 根据角色获取功能代码列表
    • 将功能代码列表编码到JWT Token中
    • 返回Token给前端
  2. 前端存储权限:

    • 从JWT Token中解析功能代码
    • 存储到localStorage中
  3. 前端权限控制:

    • 使用v-permission指令控制按钮显示
    • 指令检查用户是否拥有指定功能代码
    • 无权限时隐藏按钮
  4. 后端权限验证 (在JavaBackend中):

    • 请求到达时检查@RequirePermission注解
    • 从Token中解析功能代码
    • 验证用户是否拥有所需权限
    • 无权限时返回403错误

安全考虑

  • 权限验证在后端进行,前端控制仅为用户体验优化
  • 即使绕过前端权限控制,后端仍有安全防护
  • JWT Token中的权限信息经过签名保护,防止篡改
  • 敏感操作必须经过后端权限验证

维护要点

  • 权限配置在数据库中管理,无需修改代码
  • 可以灵活分配用户-角色-功能代码关系
  • Token过期后会重新获取最新权限信息
  • 前端权限缓存会在Token更新时同步更新