java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot Sa-Token权限认证

SpringBoot集成Sa-Token实现权限认证流程入门教程

作者:Purse Wind

本文详解SpringBoot集成Sa-Token框架的入门步骤,涵盖依赖添加、配置设置、拦截器注册、权限角色逻辑定义、设备工具类创建及登录/注销功能改造,通过注解实现鉴权,解决权限认证问题,感兴趣的朋友跟随小编一起看看吧

摘要: 本文介绍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权限认证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文