🔑 从Shiro到Sa-Token:我的权限框架迁移之旅
缘起:被Spring Security虐哭的那个下午
三年前接手公司老项目时,我面对着一坨缠绕着Spring Security和JWT的意大利面条代码。当产品经理提出新增"动态权限"需求时,看着满屏的configure(HttpSecurity http)
,我的内心是崩溃的——这堆配置到底先执行哪个过滤器?为什么我的AccessDeniedHandler
总是不生效?
直到我在GitHub闲逛时发现Sa-Token这个星星飙升的国产框架,抱着试试看的心态接入后...真香!现在连实习生都能半天搞懂权限系统了!
🌟 Sa-Token让我心动的三个瞬间
1. 五分钟完成登录认证
// 用户登录
StpUtil.login(10001);
// 检查是否登录
if(StpUtil.isLogin()){
// 获取当前用户id
Object userId = StpUtil.getLoginId();
}
// 注销登录
StpUtil.logout();
没有复杂的UserDetailsService
,不用和SecurityContextHolder
较劲,这简洁的API设计让我感动到落泪。
2. RBAC权限控制像写注释一样简单
@SaCheckPermission("user:add")
public String addUser() {
return "新增用户成功";
}
// 动态权限校验
if(StpUtil.hasPermission("report:export")) {
exportReport();
}
当产品经理第18次修改权限树时,我终于可以优雅地掏出手机点奶茶而不是改三小时代码了。
3. 踢人下线还能这么玩?
// 把用户10001踢下线
StpUtil.kickout(10001);
// 查询所有在线用户
List<String> loginIdList = StpUtil.searchSessionId("", 0, 10);
终于不用去Redis里扒拉token了!上次老板问"能不能让测试账号只能在上班时间登录",我用Sa-Token的路由拦截功能十分钟就搞定了。
🛠️ 我的实战踩坑指南
1. 会话存储选型
- 默认内存存储适合测试环境
生产环境推荐Redis插件:
<dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-dao-redis</artifactId> <version>1.30.0</version> </dependency>
2. 自定义Token策略
@Configuration
public class SaTokenConfig {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@PostConstruct
public void init() {
SaManager.setStpInterface(new StpInterfaceImpl());
SaManager.setSaTokenDao(new SaTokenDaoRedis(redisTemplate));
SaManager.setSaTokenAction(new SaTokenActionImpl(){
// 自定义token生成策略
@Override
public String createToken(Object loginId, String loginType) {
return SecureUtil.md5(loginId + ":" + System.currentTimeMillis());
}
});
}
}
3. 微服务场景下的妙用
sa-token:
is-share: true # 开启共享模式
token-name: satoken
timeout: 2592000 # 30天过期
activity-timeout: -1 # 无操作不踢人
token-style: uuid
配合网关统一鉴权,各服务再也不用重复写拦截器了!
💡 那些让我直呼内行的设计细节
- 智能防抖设计:重复登录时自动续期token有效期,但不会生成新token
精细化会话控制:可以精确到设备类型的登录管理
// 指定设备类型登录 StpUtil.login(10001, "APP"); // 查询手机端会话 List<String> sessionList = StpUtil.searchSessionId("APP", 0, 10);
注解式鉴权:支持SpringEL表达式,满足刁钻的业务需求
@SaCheckPermission("order:delete(#id)") public String deleteOrder(@RequestParam Long id) { // 业务代码 }
- 热插拔插件:从限流插件到OAuth2.0模块,需要什么装什么
🆚 横向对比:为什么选择Sa-Token?
特性 | Spring Security | Apache Shiro | Sa-Token |
---|---|---|---|
学习曲线 | 陡峭 | 中等 | 平缓 |
文档友好度 | 碎片化 | 陈旧 | 中文完善 |
注解支持 | 复杂 | 需要AOP | 开箱即用 |
微服务支持 | 复杂 | 有限 | 原生支持 |
前后端分离支持 | 需适配 | 需适配 | 深度优化 |
🚀 我的升级打怪路线图
基础版(单体应用)
- 引入
sa-token-spring-boot-starter
- 配置白名单和拦截器
- 实现基础RBAC
- 引入
进阶版(微服务架构)
- 集成Redis统一会话存储
- 网关层统一鉴权
- 配置服务间Token透传
豪华版(安全加固)
- 启用二级认证
- 配置登录防暴破
- 接入人机验证
- 开启操作日志审计
结语:开发者最懂开发者
用了Sa-Token两年多,最让我触动的是作者在issue里的回复速度(经常凌晨还在回帖)。这个充满活力的开源社区让我明白:好的框架不仅要代码优雅,更要让开发者感受到被理解。
如果你也受够了复杂的安全框架配置,不妨给Sa-Token一个机会。它可能不会让你立刻成为架构师,但一定能让你早点下班——这年头,有什么比不用加班更让人快乐呢?😉
GitHub指路:https://github.com/dromara/sa-token
相关文档:https://sa-token.cc
(真实体验,自来水安利,没恰饭!)