当前位置: 首页 > news >正文

Sa-Token使用指南

Sa-Token使用指南

1. 基础配置

1.1 添加依赖

<!-- Sa-Token 权限认证 -->
<dependency><groupId>cn.dev33</groupId><artifactId>sa-token-spring-boot-starter</artifactId><version>1.34.0</version>
</dependency><!-- Sa-Token 整合 Redis -->
<dependency><groupId>cn.dev33</groupId><artifactId>sa-token-redis</artifactId><version>1.34.0</version>
</dependency>

1.2 配置文件

# Sa-Token配置
sa-token:# token名称token-name: Authorization# token有效期timeout: 2592000# token临时有效期activity-timeout: -1# 是否允许同一账号并发登录is-concurrent: true# 在多人登录同一账号时,是否共用一个tokenis-share: false# token风格token-style: uuid# 是否输出操作日志is-log: false# Redis配置
spring:redis:host: localhostport: 6379password: database: 0

2. 基础使用

2.1 登录认证

@RestController
@RequestMapping("/auth")
public class AuthController {@PostMapping("/login")public Result login(@RequestBody LoginDTO loginDTO) {// 验证用户名密码if("admin".equals(loginDTO.getUsername()) && "123456".equals(loginDTO.getPassword())) {// 登录成功,记录用户idStpUtil.login(10001);return Result.success();}return Result.error("登录失败");}@PostMapping("/logout")public Result logout() {StpUtil.logout();return Result.success();}@GetMapping("/check")public Result check() {// 检查是否登录if(StpUtil.isLogin()) {return Result.success("已登录");}return Result.error("未登录");}
}

2.2 权限认证

@RestController
@RequestMapping("/user")
public class UserController {@SaCheckPermission("user:add")@PostMapping("/add")public Result add() {// 需要user:add权限才能访问return Result.success();}@SaCheckRole("admin")@PostMapping("/delete")public Result delete() {// 需要admin角色才能访问return Result.success();}
}

3. 权限管理

3.1 角色权限配置

@Configuration
public class SaTokenConfig {@Beanpublic StpInterface stpInterface() {return new StpInterface() {@Overridepublic List<String> getPermissionList(Object loginId, String loginType) {// 返回此 loginId 拥有的权限列表List<String> permissionList = new ArrayList<>();if(loginId.equals(10001)) {permissionList.add("user:add");permissionList.add("user:delete");}return permissionList;}@Overridepublic List<String> getRoleList(Object loginId, String loginType) {// 返回此 loginId 拥有的角色列表List<String> roleList = new ArrayList<>();if(loginId.equals(10001)) {roleList.add("admin");}return roleList;}};}
}

3.2 全局异常处理

@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(NotLoginException.class)public Result handleNotLoginException(NotLoginException e) {return Result.error("未登录");}@ExceptionHandler(NotPermissionException.class)public Result handleNotPermissionException(NotPermissionException e) {return Result.error("无权限");}@ExceptionHandler(NotRoleException.class)public Result handleNotRoleException(NotRoleException e) {return Result.error("无角色");}
}

4. 高级功能

4.1 记住我功能

@RestController
@RequestMapping("/auth")
public class AuthController {@PostMapping("/login")public Result login(@RequestBody LoginDTO loginDTO) {if("admin".equals(loginDTO.getUsername()) && "123456".equals(loginDTO.getPassword())) {// 登录时指定是否记住我StpUtil.login(10001, loginDTO.isRememberMe());return Result.success();}return Result.error("登录失败");}
}

4.2 会话管理

@RestController
@RequestMapping("/session")
public class SessionController {@GetMapping("/info")public Result getSessionInfo() {// 获取当前会话是否登录boolean isLogin = StpUtil.isLogin();// 获取当前会话账号idObject loginId = StpUtil.getLoginId();// 获取当前会话账号id(指定类型)Integer loginIdAsInt = StpUtil.getLoginIdAsInt();// 获取当前会话的token值String tokenValue = StpUtil.getTokenValue();// 获取当前会话的token信息SaTokenInfo tokenInfo = StpUtil.getTokenInfo();Map<String, Object> info = new HashMap<>();info.put("isLogin", isLogin);info.put("loginId", loginId);info.put("loginIdAsInt", loginIdAsInt);info.put("tokenValue", tokenValue);info.put("tokenInfo", tokenInfo);return Result.success(info);}
}

4.3 踢人下线

@RestController
@RequestMapping("/auth")
public class AuthController {@PostMapping("/kickout")public Result kickout(@RequestParam Long userId) {// 将指定账号踢下线StpUtil.kickout(userId);return Result.success();}@PostMapping("/kickoutAll")public Result kickoutAll() {// 将当前账号踢下线StpUtil.kickout(StpUtil.getLoginIdAsLong());return Result.success();}
}

5. 与Spring Security集成

5.1 配置类

@Configuration
public class SaTokenConfig {@Beanpublic SaTokenContext getSaTokenContext() {return new SaTokenContextForSpring();}
}

5.2 拦截器配置

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册Sa-Token拦截器registry.addInterceptor(new SaInterceptor(handle -> {// 指定需要拦截的路径SaRouter.match("/**")// 排除登录接口.notMatch("/auth/login")// 检查是否登录.check(r -> StpUtil.checkLogin());})).addPathPatterns("/**");}
}

6. 与Redis集成

6.1 配置类

@Configuration
public class SaTokenConfig {@Beanpublic SaTokenDao getSaTokenDao() {return new SaTokenDaoRedis();}
}

6.2 Redis配置

spring:redis:host: localhostport: 6379password: database: 0# 连接超时时间timeout: 10slettuce:pool:# 连接池最大连接数max-active: 200# 连接池最大阻塞等待时间max-wait: -1ms# 连接池中的最大空闲连接max-idle: 10# 连接池中的最小空闲连接min-idle: 0

7. 实际应用示例

7.1 用户登录注册

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public void register(UserRegisterDTO dto) {// 检查用户名是否存在if(userMapper.existsByUsername(dto.getUsername())) {throw new BusinessException("用户名已存在");}// 创建用户User user = new User();user.setUsername(dto.getUsername());user.setPassword(encryptPassword(dto.getPassword()));userMapper.insert(user);}public LoginVO login(LoginDTO dto) {// 查询用户User user = userMapper.findByUsername(dto.getUsername());if(user == null) {throw new BusinessException("用户不存在");}// 验证密码if(!user.getPassword().equals(encryptPassword(dto.getPassword()))) {throw new BusinessException("密码错误");}// 登录StpUtil.login(user.getId());// 返回登录信息LoginVO vo = new LoginVO();vo.setToken(StpUtil.getTokenValue());vo.setUserInfo(convertToVO(user));return vo;}
}

7.2 权限控制

@RestController
@RequestMapping("/api")
public class ApiController {@SaCheckPermission("user:view")@GetMapping("/user/info")public Result getUserInfo() {Long userId = StpUtil.getLoginIdAsLong();User user = userService.getById(userId);return Result.success(user);}@SaCheckRole("admin")@PostMapping("/user/delete/{id}")public Result deleteUser(@PathVariable Long id) {userService.deleteById(id);return Result.success();}
}

8. 注意事项

  1. 安全性考虑

    • 使用HTTPS传输
    • 设置合理的token有效期
    • 定期更换token
    • 敏感操作需要二次验证
  2. 性能优化

    • 合理使用Redis缓存
    • 避免频繁的权限检查
    • 使用token续期机制
  3. 异常处理

    • 统一处理登录异常
    • 统一处理权限异常
    • 记录关键操作日志
  4. 最佳实践

    • 遵循最小权限原则
    • 实现细粒度的权限控制
    • 做好会话管理
    • 实现单点登录

相关文章:

  • 微服务调用中的“大对象陷阱”:CPU飙高问题解析与优化
  • qt QGroupButton 实现两个QPushButton的互斥
  • 游戏引擎学习第232天
  • 解决 pip install tts 报错问题-—SadTalker的AI数字人视频—未来之窗超算中心
  • tomcat 的安装与启动
  • FPGA HR Bank如何支持ODELAY问题分析
  • text-decoration: underline;不生效
  • 土建施工员备考经验分享
  • 《软件设计师》复习笔记(14.3)——设计模式
  • Android12 ServiceManager::addService源码解读
  • Django 结合 Vue 实现简单管理系统的详解
  • JDBC 与 MyBatis 详解:从基础到实践
  • 7、生命周期:魔法的呼吸节奏——React 19 新版钩子
  • Qt 入门 5 之其他窗口部件
  • webgl入门实例-11WebGL 视图矩阵 (View Matrix)基本概念
  • 6.6 “3步调用ChatGPT打造高可靠Python调度器,零依赖实现定时任务自动化“
  • [Unity]-[UI]-[Prefab] 关于UGUI UI Prefab的制作技巧
  • 数据结构——顺序表(C语言实现)
  • 论文阅读:2024 arxiv AI Safety in Generative AI Large Language Models: A Survey
  • Odoo:免费开源的轧制品行业管理软件
  • 报告:去年物业服务百强企业营业收入均值同比增长3.52%
  • 恒安集团创始人许连捷逝世
  • 睿远基金傅鹏博、赵枫股票仓位再提升,寒武纪、分众传媒分别首进持仓前十
  • 分析|开门红:一季度GDP增长5.4%超预期,市场活力信心增强
  • 秦洪看盘|分歧渐显,短线缩量震荡