Sa-Token 基础及 Spring Boot 集成指南

一、Sa-Token 简介

Sa-Token 是一个轻量级 Java 权限认证框架,主要解决登录认证、权限认证、单点登录、OAuth2.0、分布式 Session 会话等一系列与权限相关的问题。相比于 Shiro 和 Spring Security,Sa-Token 具有以下特点:

  1. 简单易用:API 设计直观,学习成本低
  2. 功能全面:覆盖大部分认证授权场景
  3. 轻量高效:不依赖复杂设计,性能优异
  4. 模块化设计:可按需引入功能模块
  5. 良好扩展性:支持自定义各种组件

二、核心概念

1. 登录认证流程

用户登录 -> 生成Token -> 存储Token -> 返回给客户端
客户端携带Token -> 服务器验证Token -> 访问受保护资源

2. 核心组件

  • StpUtil:核心工具类,提供登录、注销、权限校验等操作
  • SaTokenConfig:配置类,可自定义各种参数
  • SaInterceptor:拦截器,实现路由拦截鉴权
  • SaTokenDao:Token 持久层接口,默认内存实现,可扩展为 Redis

3. 主要功能

  • 登录认证
  • 权限认证(角色/权限)
  • Session 管理
  • 踢人下线
  • 多账号体系
  • 单点登录
  • 模拟他人账号
  • 临时身份切换

三、Spring Boot 集成实战

1. 添加依赖

<!-- Sa-Token 核心包 -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>最新版本</version>
</dependency>

<!-- 如果使用Redis持久化 -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-dao-redis</artifactId>
    <version>最新版本</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

2. 基础配置

# application.yml
sa-token:
  # token名称 (同时也是cookie名称)
  token-name: satoken
  # token有效期,单位s 默认30天
  timeout: 2592000
  # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
  activity-timeout: -1
  # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
  is-concurrent: true
  # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
  is-share: true
  # token风格
  token-style: uuid
  # 是否输出操作日志
  is-log: true

3. 登录认证实现

@RestController
@RequestMapping("/user/")
public class UserController {

    @PostMapping("doLogin")
    public SaResult doLogin(String username, String password) {
        // 模拟数据库校验
        if("admin".equals(username) && "123456".equals(password)) {
            // 登录成功,生成Token
            StpUtil.login(10001);
            return SaResult.ok("登录成功").setData(StpUtil.getTokenInfo());
        }
        return SaResult.error("登录失败");
    }

    // 查询登录状态
    @GetMapping("isLogin")
    public SaResult isLogin() {
        return SaResult.ok("是否登录:" + StpUtil.isLogin());
    }

    // 退出登录
    @GetMapping("logout")
    public SaResult logout() {
        StpUtil.logout();
        return SaResult.ok();
    }
}

4. 权限认证实现

@RestController
@RequestMapping("/admin/")
public class AdminController {

    // 权限校验:必须具有admin权限才能进入
    @SaCheckPermission("admin")
    @GetMapping("menu")
    public SaResult menu() {
        return SaResult.data("管理员菜单");
    }

    // 角色校验:必须具有super-admin角色才能进入
    @SaCheckRole("super-admin")
    @GetMapping("settings")
    public SaResult settings() {
        return SaResult.data("系统设置");
    }

    // 二级认证:必须输入密码进行二次验证后才能进入
    @SaCheckSafe()
    @GetMapping("criticalOperation")
    public SaResult criticalOperation() {
        return SaResult.data("关键操作");
    }
}

5. 全局拦截器配置

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    // 注册Sa-Token的注解拦截器,打开注解式鉴权功能
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册注解拦截器
        registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
    }
}

四、进阶功能

1. Redis 集成(分布式会话)

# application.yml
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: 
    database: 0

sa-token:
  # 配置Token持久化到Redis
  is-share: true
  is-read-body: false
  is-read-head: true
  is-v: false
  token-prefix: "satoken:"
  jwt-secret-key: null
  id-token-timeout: 86400
  dao: "redis"

2. 自定义会话管理

@Component
public class CustomSaTokenDao extends SaTokenDaoDefaultImpl {
    // 重写数据访问层方法,例如使用MongoDB存储
    @Override
    public String get(String key) {
        // 自定义实现
        return super.get(key);
    }
    
    @Override
    public void set(String key, String value, long timeout) {
        // 自定义实现
        super.set(key, value, timeout);
    }
}

3. 注解鉴权

Sa-Token 提供丰富的注解用于权限控制:

  • @SaCheckLogin: 登录校验
  • @SaCheckRole("admin"): 角色校验
  • @SaCheckPermission("user:add"): 权限校验
  • @SaCheckSafe: 二级认证校验
  • @SaCheckBasic: HttpBasic校验

4. 路由拦截鉴权

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SaInterceptor(handler -> {
            // 登录校验 -- 拦截所有路由
            SaRouter.match("/**").check(r -> StpUtil.checkLogin());
            
            // 角色校验 -- 拦截以 admin 开头的路由
            SaRouter.match("/admin/**").check(r -> StpUtil.checkRole("admin"));
            
            // 权限校验 -- 不同模块校验不同权限
            SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
            SaRouter.match("/order/**", r -> StpUtil.checkPermission("order"));
        })).addPathPatterns("/**");
    }
}

五、最佳实践

  1. Token 安全

    • 使用 HTTPS
    • 设置合理的 token 有效期
    • 避免 token 在 URL 中传输
    • 实现 token 续期机制
  2. 权限设计

    • 遵循最小权限原则
    • 使用 RBAC (基于角色的访问控制) 模型
    • 实现权限缓存机制
  3. 性能优化

    • 对于分布式系统使用 Redis 存储 token
    • 合理设置 token 的过期时间
    • 实现本地缓存减少持久层访问
  4. 监控与日志

    • 记录关键认证操作
    • 监控异常登录行为
    • 实现登录设备管理

六、常见问题解决方案

  1. Token 失效问题

    • 检查 token 过期时间设置
    • 验证 token 持久化是否正常工作
    • 检查是否有并发登录冲突
  2. 跨域问题

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedMethods("*")
                    .allowedHeaders("*")
                    .exposedHeaders("satoken"); // 重点暴露satoken头
        }
    }
    
  3. 自定义响应格式

    @RestControllerAdvice
    public class GlobalExceptionHandler {
        // 拦截所有未处理的SaToken异常
        @ExceptionHandler(SaTokenException.class)
        public SaResult handlerSaTokenException(SaTokenException e) {
            return SaResult.error(e.getMessage());
        }
    }
    
  4. 多账号体系

    // 对于不同的账号体系,可以使用不同的StpUtil
    StpUtil.stpLogic("user").login(10001);  // 用户体系登录
    StpUtil.stpLogic("admin").login(1);     // 管理员体系登录
    

七、总结

Sa-Token 作为一个轻量级的权限认证框架,通过简单的 API 设计和丰富的功能,能够满足大多数应用的认证授权需求。与 Spring Boot 的集成非常简便,通过少量配置即可实现强大的权限控制功能。

相比传统的 Shiro 和 Spring Security,Sa-Token 的学习曲线更为平缓,且针对常见场景提供了开箱即用的解决方案。特别是对于中小型项目,Sa-Token 能够显著降低权限系统的开发成本。

在实际项目中,建议根据业务需求选择合适的持久化方案(内存或 Redis),合理设计权限模型,并遵循安全最佳实践,以构建安全可靠的认证授权系统。

03-08
### Sa-Token Java Token管理框架概述 Sa-Token 是一个专注于权限认证的轻量级 Java 框架,旨在简化并优化应用程序的安全机制[^1]。此框架不仅能够处理传统的登录验证,还支持更复杂的场景如单点登录(Single Sign-On, SSO),OAuth2.0协议实现,以及针对分布式系统的会话管理和微服务架构下的网关鉴权功能。 #### 主要特性 - **全面覆盖安全需求**:从基本的身份验证到细粒度的角色级别授权控制,再到跨多个应用间的统一身份识别。 - **易于集成与配置**:开发者可以通过阅读详细的官方文档快速上手,在现有 Spring Boot 项目中无缝引入 Sa-Token 的强大能力[^3]。 - **灵活性高**:无论是小型Web应用还是大型企业级解决方案,都能找到适合自己的部署方式;同时也提供了丰富的API供二次开发人员定制化扩展[^2]。 #### 实际应用场景示例 考虑这样一个例子来说明如何利用 Sa-Token 进行不同级别的访问控制: 当尝试调用受保护资源时(比如删除操作),如果当前用户的令牌所代表的身份不具备相应权限,则请求会被拒绝。具体来说就是 `saToken-normal` 用户仅拥有查看数据的权利而无修改或移除它们的能力,因此对于涉及更改数据库记录的操作将会返回错误响应。相反地,具有管理员(`admin`)角色凭证的人就可以顺利完成此类任务[^4]。 ```java @RestController @RequestMapping("/api") public class TestController { @GetMapping("/delete/{id}") public String delete(@PathVariable Long id) { // 假设这里执行了一些业务逻辑... return "删除成功"; } } ``` 上述代码片段展示了 RESTful API 中的一个端点定义,它接受 GET 请求用于模拟删除动作。实际环境中应当采用 POST 或 DELETE 方法更为恰当,并且需要加入必要的参数校验和异常捕获机制以增强健壮性和安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值