一、前言
完整实例代码及测试界面
下载地址:https://github.com/yzk2356911358-svg/sa-token


在后台管理系统、ERP、OA 等项目中,权限认证几乎是必不可少的模块。
传统方案中,很多项目会使用 Spring Security 或 Shiro,但实际开发中你会发现:
-
Spring Security 学习成本高、配置复杂
-
Shiro 已停止活跃维护(尤其在 Spring Boot 3 之后)
而 Sa-Token 作为一款国产轻量级权限认证框架:
-
API 简单
-
注解清晰
-
非侵入式
-
非常适合 中小型后台系统 / 内部管理系统
本文将通过一个 Spring Boot + Sa-Token + JPA + MySQL 的实战项目,讲解:
如何快速实现 登录认证 + RBAC 权限控制
二、Sa-Token 简介
Sa-Token 是一个 轻量级 Java 权限认证框架,核心功能包括:
-
登录认证
-
会话管理
-
权限校验
-
角色校验
-
单点登录
-
踢人下线
官方理念很明确:
只做权限认证,不接管你的业务
这也是它比 Spring Security 更灵活、更易上手的原因。
三、项目技术栈
-
Spring Boot 3.x
-
Sa-Token 1.38.x
-
Spring Data JPA
-
MySQL
-
Thymeleaf
项目目标:
✔ 登录 / 退出
✔ 登录态校验
✔ RBAC(用户 / 角色 / 权限)
✔ 注解式权限控制
四、RBAC 数据模型设计
经典 RBAC(Role-Based Access Control)模型:
用户(User) → 角色(Role) → 权限(Permission)
1️⃣ 用户表(sys_user)
id | username | password
2️⃣ 角色表(sys_role)
id | code | name
3️⃣ 权限表(sys_permission)
id | code | name
4️⃣ 关系表
-
用户-角色:sys_user_role
-
角色-权限:sys_role_permission
五、引入 Sa-Token 依赖
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.10-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.rbac</groupId>
<artifactId>sa-token</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sa-token</name>
<description>Demo project for Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>1.38.0</version>
</dependency>
<!-- Sa-Token 整合 Redis (使用jackson序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>1.38.0</version>
</dependency>
<!-- 提供Redis连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Sa-Token 整合 jwt -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<version>1.38.0</version>
</dependency>
<!-- Spring Security Crypto -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</project>
六、Sa-Token 基础配置
spring:
application:
name: sa-token
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/sa_token?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: rootroot
jpa:
show-sql: true
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.MySQLDialect
sa-token:
# token名称 (同时也是cookie名称)
token-name: satoken
# token有效期,单位s 默认30天, -1代表永久有效
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
active-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: false
# token风格
token-style: uuid
# 是否输出操作日志
is-log: true
server:
port: 8080
七、登录认证实现
1️⃣ 登录逻辑
@Service public class AuthService { @Resource private UserRepository userRepository; public boolean login(String username, String password) { User user = userRepository.findByUsername(username); if (user == null || !user.getPassword().equals(password)) { return false; } StpUtil.login(user.getId()); return true; } }
2️⃣ Controller
@PostMapping("/login") public String doLogin(String username, String password) { if (authService.login(username, password)) { return "redirect:/index"; } return "login"; }
八、登录态校验(核心)
Sa-Token 的优势之一就是 注解式鉴权。
登录校验
@SaCheckLogin @GetMapping("/index") public String index() { return "index"; }
未登录访问时,Sa-Token 会直接返回 401。
九、Sa-Token + RBAC 权限控制
1️⃣ 实现 StpInterface
@Component public class StpInterfaceImpl implements StpInterface { @Resource private UserRepository userRepository; @Override public List<String> getPermissionList(Object loginId, String loginType) { User user = userRepository.findById((Long) loginId).orElse(null); if (user == null) return List.of(); return user.getRoles().stream() .flatMap(role -> role.getPermissions().stream()) .map(Permission::getCode) .distinct() .toList(); } @Override public List<String> getRoleList(Object loginId, String loginType) { User user = userRepository.findById((Long) loginId).orElse(null); if (user == null) return List.of(); return user.getRoles().stream() .map(Role::getCode) .toList(); } }
2️⃣ 权限注解控制接口
@SaCheckPermission("user:add") @PostMapping("/user/add") public String addUser() { return "ok"; }
3️⃣ 角色校验
@SaCheckRole("admin") @GetMapping("/admin") public String adminPage() { return "admin"; }
十、Thymeleaf 中的权限控制
Sa-Token 提供了 Thymeleaf 工具类:
<li th:if="${#sa.hasPermission('user:list')}"> 用户管理 </li>
这样可以实现 前端菜单级权限控制。
十一、Sa-Token 的优点总结
✔ API 简单,学习成本低
✔ 注解式鉴权,代码清晰
✔ 不侵入 Spring Security 体系
✔ 适合后台管理系统、内部系统
✔ 国人维护,中文文档完善
十二、适用场景
-
ERP / OA 系统
-
内部管理后台
-
运维平台
-
中小型后台项目
如果你不想被 Spring Security 的配置折磨,Sa-Token 是一个非常好的选择。
十三、结语
Sa-Token 并不是要取代 Spring Security,而是给了开发者一个 更轻、更自由的权限认证选择。
对于大多数后台管理系统来说:
Sa-Token + RBAC = 足够、清晰、好维护