SpringBoot整合Sa-Token实现权限认证的示例代码
权限认证是每个后台系统都绕不过去的功能。Shiro 配置繁琐、Spring Security 学习曲线陡峭。Sa-Token 是一个轻量级的 Java 权限认证框架,API 设计简洁,几行代码就能集成到 SpringBoot 中。
一、Sa-Token 简介
相比 Spring Security 和 Shiro,Sa-Token 最大的优势就是简单:
| 功能 | Sa-Token | Shiro | Spring Security |
|---|---|---|---|
| 登录认证 | StpUtil.login() | Subject.login() | 复杂配置 |
| 权限校验 | @SaCheckPermission | 配置繁琐 | @PreAuthorize |
| 踢人下线 | StpUtil.kickout() | 需要自己实现 | 需要自己实现 |
| Redis 集成 | 加配置一行 | 要写代码 | 默认支持 |
核心特点: 零配置、API 简单、内置 Redis 集成、支持 OAuth2。
二、快速集成
1. 引入依赖
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.37.0</version>
</dependency>2. 配置(application.yml)
sa-token: # token 名称(默认 satoken) token-name: token # token 有效期(秒,30天) timeout: 2592000 # token 最低活跃频率(秒,-1 不续签) active-timeout: -1 # 是否允许同一账号多地同时登录(true 允许多端登录) is-concurrent: true # 多人登录时,是否踢掉已登录的(false 不踢) is-share: false # token 风格 token-style: uuid # 是否输出操作日志 is-log: true
就这么两配置,不需要别的 XML 或配置类。
三、登录认证
@RestController
@RequestMapping("/auth")
public class AuthController {
/**
* 登录接口
*/
@PostMapping("/login")
public ResultVO<String> login(@RequestParam String username,
@RequestParam String password) {
// 校验用户名密码(这里以 admin/123456 为例)
if (!"admin".equals(username) || !"123456".equals(password)) {
return ResultVO.error(401, "用户名或密码错误");
}
// 执行登录(Sa-Token 自动生成 token)
StpUtil.login(1001); // 参数为用户ID
// 获取 token 返回给前端
String token = StpUtil.getTokenInfo().getTokenValue();
return ResultVO.success(token);
}
/**
* 退出登录
*/
@PostMapping("/logout")
public ResultVO<?> logout() {
StpUtil.logout();
return ResultVO.success("退出成功");
}
/**
* 获取当前登录用户信息
*/
@GetMapping("/info")
public ResultVO<?> info() {
// 获取当前用户ID
long userId = StpUtil.getLoginIdAsLong();
return ResultVO.success("当前用户: " + userId);
}
}
前端请求时在 header 中携带 token:
Authorization: satoken Content-Type: application/json
四、拦截器配置(需要登录才能访问)
@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 的路由拦截器
registry.addInterceptor(new SaInterceptor())
.addPathPatterns("/**")
.excludePathPatterns(
"/auth/login", // 登录接口不拦截
"/auth/register",
"/doc.html", // Swagger 文档
"/v3/**",
"/swagger-ui/**"
);
}
}
配置后,所有未登录的请求会返回 401 未登录,不需要自己写拦截器。
五、权限认证
1. 给用户分配权限
@Service
public class UserService {
/**
* 获取用户的权限列表(从数据库查询)
*/
public List<String> getPermissions(Long userId) {
// 实际项目中从数据库查询
if (userId == 1001) {
return Arrays.asList("user.add", "user.delete", "user.update", "user.query");
}
return Arrays.asList("user.query");
}
/**
* 获取用户的角色列表
*/
public List<String> getRoles(Long userId) {
if (userId == 1001) {
return Arrays.asList("admin");
}
return Arrays.asList("user");
}
}
2. 注册权限接口
@Component
public class StpInterfaceImpl implements StpInterface {
@Autowired
private UserService userService;
/**
* 获取用户的权限列表(框架自动调用)
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
Long userId = Long.parseLong(loginId.toString());
return userService.getPermissions(userId);
}
/**
* 获取用户的角色列表
*/
@Override
public List<String> getRoleList(Object loginId, String loginType) {
Long userId = Long.parseLong(loginId.toString());
return userService.getRoles(userId);
}
}
3. 使用注解控制权限
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/list")
@SaCheckPermission("user.query") // 需要 user.query 权限
public ResultVO<?> list() {
return ResultVO.success("查询用户列表");
}
@PostMapping("/add")
@SaCheckPermission("user.add") // 需要 user.add 权限
public ResultVO<?> add() {
return ResultVO.success("新增用户");
}
@DeleteMapping("/delete")
@SaCheckPermission("user.delete") // 需要 user.delete 权限
public ResultVO<?> delete() {
return ResultVO.success("删除用户");
}
@PutMapping("/update")
@SaCheckPermission("user.update") // 需要 user.update 权限
public ResultVO<?> update() {
return ResultVO.success("修改用户");
}
}
4. 角色校验
@GetMapping("/admin/dashboard")
@SaCheckRole("admin") // 只有 admin 角色能访问
public ResultVO<?> dashboard() {
return ResultVO.success("管理后台面板");
}
5. 在代码中手动校验
// 校验是否有权限(没有则抛异常)
StpUtil.checkPermission("user.add");
// 校验权限(返回 boolean)
if (StpUtil.hasPermission("user.delete")) {
// 有权限就执行
}
// 校验角色
StpUtil.checkRole("admin");
六、踢人下线
管理员可以强制让某个用户下线(比如检测到异常登录):
@PostMapping("/kickout")
@SaCheckRole("admin")
public ResultVO<?> kickout(Long userId) {
// 让指定用户被踢下线
StpUtil.kickout(userId);
return ResultVO.success("已强制用户 " + userId + " 下线");
}
被踢的用户下次请求时会收到 401,提示"Token 已被踢下线"。
七、记住我(7天免登录)
// 登录时设置 rememberMe = true,token 有效期自动延长 StpUtil.login(1001, true); // 不传或 false 则使用配置的 timeout StpUtil.login(1001);
在配置中设置记住我的时长:
sa-token: # 记住我模式的有效期(单位:秒,7天) activity-timeout: 604800
八、单点登录(SSO)
Sa-Token 内置了单点登录方案,几行配置就能实现多系统统一登录:
sa-token:
sso:
# SSO 认证中心地址
auth-url: http://sso-server.com:9000/auth
# 是否开启单点登录
is-sso: true详细用法参考 Sa-Token 官方文档(sso 章节)。
九、与你的秒杀系统集成
@RestController
@RequestMapping("/api/seckill")
@SaCheckLogin // 整个类需要登录才能访问
public class SeckillController {
@PostMapping("/do/{productId}")
@SaCheckPermission("seckill.buy") // 需要秒杀权限
public ResultVO<?> doSeckill(@PathVariable Long productId) {
// 获取当前登录用户
long userId = StpUtil.getLoginIdAsLong();
return seckillService.doSeckill(productId, userId, "用户" + userId);
}
}
只用加两个注解,权限控制就搞定了。 比之前可能用的拦截器+Session 方式省事很多。
十、Sa-Token 常用 API 速查
// 登录认证
StpUtil.login(1001); // 登录
StpUtil.logout(); // 登出
StpUtil.getLoginId(); // 获取当前用户ID
StpUtil.isLogin(); // 是否登录
StpUtil.checkLogin(); // 校验登录(未登录抛异常)
// 权限校验
StpUtil.checkPermission("user.add"); // 校验权限
StpUtil.hasPermission("user.add"); // 是否拥有权限
StpUtil.checkRole("admin"); // 校验角色
StpUtil.hasRole("admin"); // 是否拥有角色
// 踢人
StpUtil.kickout(1001); // 踢用户下线
StpUtil.logout(1001); // 让用户注销(踢下线且清除记录)
// Token 管理
StpUtil.getTokenValue(); // 获取当前 token
StpUtil.getTokenInfo(); // 获取 token 详细信息
总结: Sa-Token 的核心就两句话——StpUtil.login() 登录,@SaCheckPermission 鉴权。比 Shiro 的 Subject + Realm + 配置文件那一套简洁太多了。
以上就是SpringBoot整合Sa-Token实现权限认证的示例代码的详细内容,更多关于SpringBoot Sa-Token权限认证的资料请关注脚本之家其它相关文章!
相关文章
Spring的@ConfigurationProperties注解详解
这篇文章主要介绍了Spring的@ConfigurationProperties注解详解,@ConfigurationProperties该注解是用来获取yml或者properties配置文件的配置信息,下面根据一些配置信息给出案例代码进行讲解,需要的朋友可以参考下2023-11-11


最新评论