1. 为什么选择SA-Token?从“造轮子”到“用轮子”的转变
大家好,我是老张,一个在Java后端摸爬滚打了十来年的老码农。这些年,权限认证这个“坑”我踩过无数次。从最早自己手撸拦截器,到用Shiro、Spring Security,再到后来项目上了微服务,分布式会话和鉴权更是让人头疼。每次新项目启动,光是搭建这套权限框架,就得花上好几天,配置繁琐不说,一旦业务逻辑复杂起来,代码里到处都是权限判断,维护起来简直是噩梦。
直到我遇到了SA-Token。说实话,第一次看到它的时候,我有点怀疑:一个国产的、轻量级的框架,能搞定这么多事儿?但抱着试试看的心态在一个内部系统里用了一下,结果真香了。它最打动我的地方,就是**“简单”**。这种简单不是功能简陋,而是设计上的优雅和API的直观。它把登录、鉴权、会话这些复杂的概念,封装成了像 StpUtil.login(userId)、StpUtil.checkPermission(“user.add”) 这样一眼就能看懂的方法。开发者不用再关心Token是怎么生成的、Session存在了哪里、拦截器怎么配置,只需要关注最核心的业务逻辑:谁,在什么情况下,能做什么事。
SA-Token解决的不仅仅是登录验证。在实际项目中,我们面临的是一系列连锁问题:用户踢下线怎么处理?前后端分离后Token如何安全传递?微服务架构下,多个服务如何共享登录状态?按钮级别的细粒度权限如何优雅控制?SA-Token为这一系列问题提供了一套开箱即用的解决方案。它内置了会话管理、角色权限、踢人下线、同端互斥登录、自动续签、二级认证等特性,甚至对OAuth2.0和分布式会话(集成Redis)都有很好的支持。这意味着,我们终于可以从重复“造轮子”和配置“玄学”中解放出来,把宝贵的时间投入到业务创新上。
所以,如果你正在为一个新的Spring Boot项目选型权限框架,或者对现有项目中繁琐的权限代码感到疲惫,那么这篇深度整合实践指南就是为你准备的。我会带你从零开始,一步步将SA-Token集成到Spring Boot中,并分享我在真实项目中应用它时总结的技巧和避坑经验。我们不止讲“怎么配”,更要讲“为什么这么配”,以及“在实际业务中怎么用好”。
2. 五分钟快速上手:从零搭建一个可运行的Demo
光说不练假把式,咱们先抛开所有复杂概念,用最快速度搭建一个能登录、能鉴权的可运行项目。这个过程我会尽量模拟一个新项目的初始化,让你感受一下SA-Token的“快”。
第一步:创建项目并引入依赖。 我习惯用Spring Initializr,选上Spring Web依赖就行。然后打开pom.xml,引入SA-Token的核心启动器。这里有个关键点:Spring Boot 2.x和3.x的依赖是不同的,千万别搞错。我目前主流项目还是Spring Boot 2.7.x,所以引入的是这个:
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.37.0</version> <!-- 写文章时最新版,请以官网为准 -->
</dependency>
如果你用的是Spring Boot 3.0以上,artifactId要换成 sa-token-spring-boot3-starter。版本号建议去SA-Token的GitHub仓库或官方文档查看最新稳定版。
第二步:写一个最简单的配置。 在application.yml里,我们只需要加几行最基础的配置,让项目先跑起来:
sa-token:
token-name: satoken # Token的名字,也是Cookie的名字,你可以按喜好改
timeout: 2592000 # Token有效期,默认30天(单位秒)。-1代表永久有效,生产环境慎用
is-log: true # 开启日志,初学阶段打开,方便看框架内部执行过程
对,初期配置就这么简单。其他像是否允许并发登录、Token风格等高级选项,我们后面再细说。
第三步:实现登录接口。 我们来创建一个AuthController。这里我模拟一个用户数据库查询和密码校验的过程(实际项目请务必连接数据库并加密比对):
@RestController
@RequestMapping("/auth")
public class AuthController {
@PostMapping("/login")
public SaResult login(@RequestParam String username, @RequestParam String password) {
// 1. 模拟数据库查询(实际项目请替换为MyBatis/ JPA操作)
if (!"zhangsan".equals(username) || !"123456".equals(password)) {
return SaResult.error("用户名或密码错误");
}
// 2. 假设查询到的用户ID是 10001
long userId = 10001L;
// 3. 核心登录代码:标记当前会话为此用户ID
StpUtil.login(userId);
// 4. 获取当前会话的Token值,返回给前端
String tokenValue = StpUtil.getTokenValue();
return SaResult.ok("登录成功").setData(tokenValue);
}
@GetMapping("/check")
public SaResult checkLogin() {
// 判断当前会话是否登录
if (StpUtil.isLogin()) {
return SaResult.ok("已登录,用户ID: " + StpUtil.getLoginId());
} else {
return SaResult.error("未登录");
}
}
@PostMapping("/logout")
public SaResult logout() {
StpUtil.logout();
return SaResult.ok("退出成功");
}
}
启动你的Spring Boot应用,用Postman测试一下:
- POST请求
http://localhost:8080/auth/login?username=zhangsan&password=123456,你会收到登录成功的信息和一个Token字符串。 - 这个Token会被SA-Token自动放在本次请求的响应头
satoken里(如果你用Postman,可以在Headers里看到)。后续请求,前端需要把这个Token值放在请求头的satoken字段中。 - 带着这个Token头,请求
GET /a


3130

被折叠的 条评论
为什么被折叠?



