🔑 从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

配合网关统一鉴权,各服务再也不用重复写拦截器了!


💡 那些让我直呼内行的设计细节

  1. 智能防抖设计:重复登录时自动续期token有效期,但不会生成新token
  2. 精细化会话控制:可以精确到设备类型的登录管理

    // 指定设备类型登录
    StpUtil.login(10001, "APP");
    
    // 查询手机端会话
    List<String> sessionList = StpUtil.searchSessionId("APP", 0, 10);
  3. 注解式鉴权:支持SpringEL表达式,满足刁钻的业务需求

    @SaCheckPermission("order:delete(#id)")
    public String deleteOrder(@RequestParam Long id) {
     // 业务代码
    }
  4. 热插拔插件:从限流插件到OAuth2.0模块,需要什么装什么

🆚 横向对比:为什么选择Sa-Token?

特性Spring SecurityApache ShiroSa-Token
学习曲线陡峭中等平缓
文档友好度碎片化陈旧中文完善
注解支持复杂需要AOP开箱即用
微服务支持复杂有限原生支持
前后端分离支持需适配需适配深度优化

🚀 我的升级打怪路线图

  1. 基础版(单体应用)

    • 引入sa-token-spring-boot-starter
    • 配置白名单和拦截器
    • 实现基础RBAC
  2. 进阶版(微服务架构)

    • 集成Redis统一会话存储
    • 网关层统一鉴权
    • 配置服务间Token透传
  3. 豪华版(安全加固)

    • 启用二级认证
    • 配置登录防暴破
    • 接入人机验证
    • 开启操作日志审计

结语:开发者最懂开发者

用了Sa-Token两年多,最让我触动的是作者在issue里的回复速度(经常凌晨还在回帖)。这个充满活力的开源社区让我明白:好的框架不仅要代码优雅,更要让开发者感受到被理解。

如果你也受够了复杂的安全框架配置,不妨给Sa-Token一个机会。它可能不会让你立刻成为架构师,但一定能让你早点下班——这年头,有什么比不用加班更让人快乐呢?😉

GitHub指路https://github.com/dromara/sa-token

相关文档https://sa-token.cc

(真实体验,自来水安利,没恰饭!)

最后修改:2025 年 04 月 10 日
如果觉得我的文章对你有用,请随意赞赏