目录
用户登录流程
前端
- 点击
login.vue
中的登录按钮 - 调用
login.vue
中的handleLogin
方法 - 调用
store/mondles/user.js
中的login
方法,将返回结果存入useUserStore对象中(用于管理用户相关的状态和操作) - 调用
api/login.js
中的login
方法 - 调用
utils/request.js
中的service
实例基于axios发送ajax请求(.env.development文件设置了统一请求路径前缀)
后端
SysLoginController
在admin
模块中system.SysLoginController
类的login
方法接收前端登录请求
SysLoginService
在framework
模块framework.web.service.SysLoginService
类的login
方法处理登录逻辑
- 验证码校验
- 登录前置校验
- 校验账号的合法性(是否存在、删除、锁定)
- 用户登录认证
- 认证通过后,创建登录用户对象LoginUser包括用户ID、部门ID、用户信息和用户权限信息
- 登录成功,记录日志
- 修改用户表更新登录信息
- 生成token
动态菜单
前端
前端在登录后
- 在全局
permission.js
中的router.beforeEach
方法用于在用户导航到不同路由之前进行一些预处理。 - 调用
store/mondles/permission.js
中的getRouters
方法,获取登录用户有权限的菜单,前端根据路由动态展示。
后端
数据库表
功能逻辑
在 admin
模块中SysLoginController
类
getRouters()
:获取当前用户的菜单目录权限
返回结果
具体执行流程如下图
菜单权限
前端封装了一个指令权限,能简单快速的实现目录菜单级别的权限判断。
使用角色字符串 v-hasRole@/directive/permission/hasRole.js
// 单个
<el-button v-hasRole="['admin']">管理员才能看到</el-button>
// 多个
<el-button v-hasRole="['role1', 'role2']">包含角色才能看到</el-button>
动态按钮
前端
前端在登录后
- 调用
api/login.js
中的getInfo
方法
后端
数据库表
功能逻辑
在 admin
模块中SysLoginController
类
getInfo()
:获取当前用户的操作按钮权限getRolePermission
:查询该用户角色集合getMenuPermission
:查询该用户按钮权限集合
返回结果
按钮权限
前端封装了一个指令权限,能简单快速的实现按钮级别的权限判断。
使用权限字符串 v-hasPermi:@/directive/permission/hasPermi.js
// 单个
<el-button v-hasPermi="['system:user:add']">存在权限字符串才能看到</el-button>
// 多个
<el-button v-hasPermi="['system:user:add', 'system:user:edit']">包含权限字符串才能看到</el-button>
接口权限注解
@PreAuthorize 注解
在若依框架中,权限的验证最核心的是使用的 Spring Security 的提供的权限注解@PreAuthorize
@PreAuthorize
是 Spring Security 框架中提供的一个安全注解,用于实现基于注解的访问控制。它允许开发者在方法级别上声明特定的安全约束,以确保只有满足指定条件的用户才能调用该方法。- 当
@PreAuthorize
注解被应用于某个方法时,Spring Security 在该方法执行前会先对当前认证的用户进行权限(分为角色权限和按钮权限两种)检查。如果检查通过,方法调用得以继续;否则,框架会抛出相应的权限异常(如 AccessDeniedException),阻止方法执行。
权限控制代码示例:
@PreAuthorize("@ss.hasPermi('course:course:list')")
@GetMapping("/list")
public TableDataInfo list(Course course) {
startPage();
List<Course> list = courseService.selectCourseList(course);
return getDataTable(list);
}
@PreAuthorize(...)
来自 Spring Security,用于在方法执行前进行权限验证。@ss.hasPermi('course:course:list')
ss
:PermissionService
类注册为 bean 对象。hasPermi
:PermissionService类中的一个方法,判断是否拥有该权限course:course:list
:接口的权限字符串
注意:在SecurityConfig类中添加
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
,@PreAuthorize才能生效
权限控制流程
权限控制方法
在 PermissionService 类中定义了许多中权限校验的方法,代码结构如下图:
不仅支持角色权限控制,还有更细粒度的按钮权限控制
方法 | 参数 | 描述 |
---|---|---|
hasPermi | String | 验证用户是否具备某权限 |
lacksPermi | String | 验证用户是否不具备某权限,与 hasPermi逻辑相反 |
hasAnyPermi | String | 验证用户是否具有以下任意一个权限 |
hasRole | String | 判断用户是否拥有某个角色 |
lacksRole | String | 验证用户是否不具备某角色,与 hasRole逻辑相反 |
hasAnyRoles | String | 验证用户是否具有以下任意一个角色,多个逗号分隔 |
使用示例
接口权限校验
// 符合system:user:list权限要求
@PreAuthorize("@ss.hasPermi('system:user:list')")
// 不符合system:user:list权限要求
@PreAuthorize("@ss.lacksPermi('system:user:list')")
// 符合system:user:add或system:user:edit权限要求即可
@PreAuthorize("@ss.hasAnyPermi('system:user:add,system:user:edit')")
角色权限校验
// 属于user角色
@PreAuthorize("@ss.hasRole('user')")
// 不属于user角色
@PreAuthorize("@ss.lacksRole('user')")
// 属于user或者admin之一
@PreAuthorize("@ss.hasAnyRoles('user,admin')")