公司动态
Sa-Token轻量级Java权限认证框架实践指南
1. 项目概述最近在重构公司后台管理系统时我选择了Sa-Token作为权限认证框架。这个轻量级Java权限认证框架确实让我眼前一亮它用极简的API解决了登录认证、权限控制、单点登录等核心问题。相比Shiro和Spring SecuritySa-Token的学习曲线平缓得多基本上半天就能上手。在实际项目中我发现Sa-Token特别适合中小型系统的权限管理需求。它内置了路由拦截、注解鉴权、会话管理等功能而且配置极其简单。比如要实现一个只有管理员才能访问的接口只需要加个SaCheckRole(admin)注解就行完全不需要写繁琐的XML配置。2. 核心需求解析2.1 登录认证设计Sa-Token的登录认证设计得非常优雅。它通过StpUtil工具类提供了一站式解决方案// 用户登录 StpUtil.login(10001); // 获取当前会话是否登录 StpUtil.isLogin(); // 获取当前会话账号id StpUtil.getLoginId();这种设计让登录状态管理变得异常简单。我特别喜欢它的无状态登录特性默认使用UUID作为token完全不需要依赖Redis等外部存储当然也支持Redis集成。2.2 权限校验实现权限校验是系统的核心功能。Sa-Token提供了三种粒度的控制方式路由拦截通过配置拦截器实现Configuration public class SaTokenConfigure implements WebMvcConfigurer { Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new SaInterceptor()) .addPathPatterns(/**) .excludePathPatterns(/user/login); } }注解鉴权直接在方法上添加注解SaCheckLogin GetMapping(/info) public String info() { return 用户信息; }代码鉴权在业务逻辑中动态校验if(!StpUtil.hasPermission(user:add)) { throw new ApiException(无权限操作); }3. 完整实现过程3.1 环境搭建首先引入Maven依赖dependency groupIdcn.dev33/groupId artifactIdsa-token-spring-boot-starter/artifactId version1.45.0/version /dependency基础配置application.ymlsa-token: token-name: satoken # token名称 timeout: 86400 # token有效期秒 is-share: true # 是否允许同一账号多地登录 is-read-body: true # 是否从请求体读取token3.2 权限模型设计我采用了经典的RBAC基于角色的访问控制模型用户表sys_user角色表sys_role权限表sys_permission用户-角色关联表sys_user_role角色-权限关联表sys_role_permission权限标识使用资源:操作格式如user:add用户新增user:delete用户删除order:query订单查询3.3 核心代码实现登录接口PostMapping(/login) public Result login(RequestBody LoginDto dto) { // 1. 验证账号密码 SysUser user userService.login(dto); // 2. 登录并返回token StpUtil.login(user.getId()); return Result.success(StpUtil.getTokenInfo()); }权限加载实现Sa-Token的StpInterfaceComponent public class StpInterfaceImpl implements StpInterface { Override public ListString getPermissionList(Object loginId, String loginType) { return permissionService.getByUserId((Long)loginId); } Override public ListString getRoleList(Object loginId, String loginType) { return roleService.getByUserId((Long)loginId); } }4. 高级功能实践4.1 单点登录集成Sa-Token的SSO集成非常简单。只需添加依赖dependency groupIdcn.dev33/groupId artifactIdsa-token-sso/artifactId version1.45.0/version /dependency然后配置SSO服务器端Configuration public class SaSsoConfig { Autowired private void configSso(SaSsoConfig config) { config .setTicketTimeout(60) // ticket有效期 .setAllowUrl(*); // 允许所有url参与单点登录 } }4.2 微服务鉴权在微服务架构下可以使用Sa-Token的网关鉴权功能网关层统一校验token服务间调用通过Feign拦截器传递token配置服务白名单// 网关鉴权过滤器 public class AuthFilter implements GlobalFilter { Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 从请求头获取token String token exchange.getRequest().getHeaders().getFirst(satoken); // 校验token if(!StpUtil.checkToken(token)) { return unauthorizedResponse(exchange); } return chain.filter(exchange); } }5. 踩坑经验分享5.1 常见问题排查权限不生效检查是否实现了StpInterface确认权限数据是否正确加载查看拦截器配置是否覆盖了目标接口Token失效异常检查token有效期配置确认多端登录配置is-share排查Redis连接问题如果使用Redis跨域问题确保前端正确携带token配置CORS允许凭证credentials5.2 性能优化建议权限缓存// 在StpInterface实现类中添加缓存 Cacheable(value user:perms, key #loginId) public ListString getPermissionList(Object loginId, String loginType) { // 查询数据库 }批量权限校验// 批量检查权限减少数据库查询 StpUtil.checkPermissionAnd(user:add, user:delete);使用Redis集群sa-token: is-share: true token-prefix: satoken: jwt-secret-key: your-secret-key6. 扩展思考在实际项目中我还探索了Sa-Token的一些高级用法多端登录管理// 指定设备类型登录 StpUtil.login(10001, PC); // 查询指定设备的会话 StpUtil.getTokenValueByLoginId(10001, APP);临时令牌生成// 生成一个只能使用一次的临时token String tempToken StpUtil.createTempToken(10001, 300);二级认证// 敏感操作前进行二次认证 if(!StpUtil.isSafe()) { throw new ApiException(请先进行安全验证); }这套权限系统上线后运行稳定权限变更能实时生效管理后台的操作日志也完整可追溯。Sa-Token的轻量设计让我们的系统性能表现优异平均响应时间在50ms以内。