SpringBoot集成Sa-Token实现权限认证流程入门教程
作者:Purse Wind
摘要: 本文介绍SpringBoot集成 Sa-Token 框架的步骤,包括添加依赖、配置文件设置、注册拦截器。还讲解了权限与角色获取逻辑定义、设备工具类创建,以及登录、用户信息获取、注销功能的改造,最后提及用注解实现鉴权。
Sa-token 介绍
Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话等一系列权限相关问题。(本节仅讲解入门内容)
SpringBoot 集成 Sa-Token
1.添加依赖
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc --> <dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-spring-boot-starter</artifactId> <version>1.44.0</version> </dependency>
注:如果你使用的是 SpringBoot 3.x,只需要将 sa-token-spring-boot-starter
修改为 sa-token-spring-boot3-starter
即可。
2.设置配置文件
spring: application: name: ai-codegen-microservice sa-token: # token 名称(同时也是 cookie 名称) token-name: satoken # token 有效期(单位:秒) 默认30天,-1 代表永久有效 timeout: 2592000 # token 最低活跃频率,如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 active-timeout: -1 # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: true # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token) is-share: false # token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik) token-style: uuid # 是否输出操作日志 is-log: true
3.创建Controller测试类
/** * 测试 Sa-Token 框架实现用户登录 */ @RestController @RequestMapping("/test/user/") public class TestSaTokenLoginController { // 测试登录,浏览器访问: http://localhost:8101/api/test/user/doLogin?username=zhang&password=123456 @RequestMapping("doLogin") public String doLogin(String username, String password) { // 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对 if ("zhang".equals(username) && "123456".equals(password)) { StpUtil.login(10001); return "登录成功"; } return "登录失败"; } // 查询登录状态,浏览器访问: http://localhost:8101/api/test/user/isLogin @RequestMapping("isLogin") public String isLogin() { return "当前会话是否登录:" + StpUtil.isLogin(); } }
然后可以通过直接访问接口地址来验证。
后端开发实现登录校验与权限检验
1.添加依赖并设置配置文件
2.注册 Sa-Token 拦截器
新建 satoken
包,在里面新建配置类 SaTokenConfigure
,注册拦截器:
@Configuration public class SaTokenConfigure implements WebMvcConfigurer { // 注册 Sa-Token 拦截器,打开注解式鉴权功能 @Override public void addInterceptors(InterceptorRegistry registry) { // 注册 Sa-Token 拦截器,打开注解式鉴权功能 registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**"); } }
然后就可以使用注解鉴权了,比如下列注解,可以平替我们项目中已经写的鉴权注解:
// 登录校验:只有登录之后才能进入该方法 @SaCheckLogin @RequestMapping("info") public String info() { return "查询用户信息"; } // 角色校验:必须具有指定角色才能进入该方法 @SaCheckRole("super-admin") @RequestMapping("add") public String add() { return "用户增加"; }
3.定义权限与角色获取逻辑
部分接口需要特定的用户权限或对应的角色才能访问,那怎么知道当前登录用户具有哪些权限或角色呢?
按照 Sa-Token 的开发模式,我们需要新建一个类,实现 StpInterface
接口。该接口提供了获取当前登录用户的权限和角色的方法,在每次调用鉴权代码时,都会执行接口中的方法。
在 satoken
包下新建类,代码如下:
@Component // 保证此类被 SpringBoot 扫描,完成 Sa-Token 的自定义权限验证扩展 public class StpInterfaceImpl implements StpInterface { /** * 返回一个账号所拥有的角色标识集合 (权限与角色可分开校验) */ @Override public List<String> getRoleList(Object loginId, String s) { // 从当前登录用户信息中获取角色 User user = (User) StpUtil.getSessionByLoginId(loginId).get(USER_LOGIN_STATE); return Collections.singletonList(user.getUserRole()); } }
4.新建设备信息获取工具类
/** * 设备工具类 */ public class DeviceUtils { /** * 根据请求获取设备信息 **/ public static String getRequestDevice(HttpServletRequest request) { String userAgentStr = request.getHeader(Header.USER_AGENT.toString()); // 使用 Hutool 解析 UserAgent UserAgent userAgent = UserAgentUtil.parse(userAgentStr); ThrowUtils.throwIf(userAgent == null, ErrorCode.OPERATION_ERROR, "非法请求"); // 默认值是 PC String device = "pc"; // 是否为小程序 if (isMiniProgram(userAgentStr)) { device = "miniProgram"; } else if (isPad(userAgentStr)) { // 是否为 Pad device = "pad"; } else if (userAgent.isMobile()) { // 是否为手机 device = "mobile"; } return device; } /** * 判断是否是小程序 * 一般通过 User-Agent 字符串中的 "MicroMessenger" 来判断是否是微信小程序 **/ private static boolean isMiniProgram(String userAgentStr) { // 判断 User-Agent 是否包含 "MicroMessenger" 表示是微信环境 return StrUtil.containsIgnoreCase(userAgentStr, "MicroMessenger") && StrUtil.containsIgnoreCase(userAgentStr, "MiniProgram"); } /** * 判断是否为平板设备 * 支持 iOS(如 iPad)和 Android 平板的检测 **/ private static boolean isPad(String userAgentStr) { // 检查 iPad 的 User-Agent 标志 boolean isIpad = StrUtil.containsIgnoreCase(userAgentStr, "iPad"); // 检查 Android 平板(包含 "Android" 且不包含 "Mobile") boolean isAndroidTablet = StrUtil.containsIgnoreCase(userAgentStr, "Android") && !StrUtil.containsIgnoreCase(userAgentStr, "Mobile"); // 如果是 iPad 或 Android 平板,则返回 true return isIpad || isAndroidTablet; } }
5.改造登录接口
修改userLogin
方法中的逻辑,需要给 Sa-Token 设置登录态,保存登录用户信息。
// Sa-Token 登录,并指定设备,同端登录互斥 StpUtil.login(user.getId(), DeviceUtils.getRequestDevice(request)); StpUtil.getSession().set(USER_LOGIN_STATE, user);
6.改造获取用户信息的逻辑
修改getLoginUser
,不再从 request.getSession()
中获取登录用户的 id,改为从 Sa-Token 中获取。
@Override public User getLoginUser(HttpServletRequest request) { // 先判断是否已登录 Object loginUserId = StpUtil.getLoginIdDefaultNull(); if (loginUserId == null) { throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); } // 从数据库查询(追求性能的话可以注释,直接走缓存) User currentUser = this.getById((String) loginUserId); if (currentUser == null) { throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); } return currentUser; }
如果用户信息几乎很少修改,可以不查数据库,直接从 Sa-Token 的 Session 中获取之前保存的用户登录态:
@Override public User getLoginUser(HttpServletRequest request) { // 先判断是否已登录 Object loginId = StpUtil.getLoginIdDefaultNull(); if (Objects.isNull(loginId)) { throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR); } return (User) StpUtil.getSessionByLoginId(loginId).get(USER_LOGIN_STATE); }
7.改造用户注销功能
改为调用 Sa-Token 的注销方法,移除登录态:
@Override public boolean userLogout(HttpServletRequest request) { StpUtil.checkLogin(); // 移除登录态 StpUtil.logout(); return true; }
8. 替换鉴权注解
如果是管理员权限的接口,打上以下注解:
@SaCheckRole(UserConstant.ADMIN_ROLE)
到此这篇关于SpringBoot集成Sa-Token实现权限认证流程入门教程的文章就介绍到这了,更多相关SpringBoot Sa-Token权限认证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!