Sa-Token 实战:如何解决 cn.dev33.satoken.exception.NotLoginException 异常

1次阅读
没有评论

共计 2221 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

在 Java 开发中,Sa-Token 是一个轻量级的权限认证框架,但新手在使用时经常会遇到 cn.dev33.satoken.exception.NotLoginException: 未能读取到有效 token 的异常。这个异常通常意味着系统无法从请求中获取到有效的登录凭证。本文将带你深入理解这个异常,并提供完整的解决方案。

Sa-Token 实战:如何解决 cn.dev33.satoken.exception.NotLoginException 异常

1. NotLoginException 异常解析

NotLoginException 异常通常在以下场景触发:

  • Token 不存在 :请求头或 Cookie 中未携带 Token
  • Token 过期 :Token 已超过预设的有效期
  • Token 无效 :Token 被篡改或格式错误
  • 主动注销 :用户主动退出登录导致 Token 失效

2. Token 存储方案对比

Sa-Token 支持两种主流的 Token 存储方式:

  • Cookie 存储
  • 优点:自动携带,浏览器原生支持
  • 缺点:跨域问题,安全性较低

  • Header 存储

  • 优点:安全性高,适合前后端分离
  • 缺点:需要前端手动设置

推荐前后端分离项目使用 Header 方式,传统 Web 项目可以使用 Cookie 方式。

3. 完整异常处理方案

全局异常拦截器配置

@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(NotLoginException.class)
    public Result handleNotLoginException(NotLoginException e) {
        // 根据不同子类型返回不同提示
        String message = "未登录";
        switch(e.getType()) {
            case NotLoginException.INVALID_TOKEN:
                message = "Token 无效";
                break;
            case NotLoginException.TOKEN_TIMEOUT:
                message = "Token 已过期";
                break;
            case NotLoginException.BE_REPLACED:
                message = "Token 已被顶下线";
                break;
        }
        return Result.fail(401, message);
    }
}

Token 生成和刷新逻辑

@RestController
@RequestMapping("/auth")
public class AuthController {@PostMapping("/login")
    public Result login(@RequestBody LoginDTO dto) {
        // 1. 验证用户名密码
        if(!"admin".equals(dto.getUsername()) || !"123456".equals(dto.getPassword())) {return Result.fail("账号或密码错误");
        }

        // 2. 生成 Token
        StpUtil.login(dto.getUsername());

        // 3. 返回 Token 信息
        return Result.success(StpUtil.getTokenInfo());
    }

    @GetMapping("/refresh")
    public Result refreshToken() {if(!StpUtil.isLogin()) {throw new NotLoginException();
        }

        // 刷新 Token 有效期
        StpUtil.renewTimeout(3600);
        return Result.success(StpUtil.getTokenInfo());
    }
}

自定义登录校验逻辑

@Configuration
public class SaTokenConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token 的拦截器
        registry.addInterceptor(new SaRouteInterceptor())
            .addPathPatterns("/**")
            .excludePathPatterns("/auth/login", "/auth/refresh");
    }
}

4. 性能优化建议

  • 合理设置 Token 过期时间
  • 普通用户:2- 4 小时
  • 高安全需求:30 分钟
  • 记住我功能:7 天

  • 并发场景处理

  • 使用 StpUtil.checkActivityTimeout() 检查活跃度
  • 启用二级缓存提高性能

5. 安全注意事项

  • 防止 Token 泄露
  • 强制 HTTPS
  • 设置 HttpOnly 和 Secure 标志

  • CSRF 防护

  • 启用 Sa-Token 的 CRSF 防护
  • 重要操作添加二次验证

6. Spring Boot 集成示例

完整 pom.xml 依赖:

<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>1.30.0</version>
</dependency>

7. 扩展思考

  • 分布式 Token 同步
  • 考虑使用 Redis 集中存储 Token
  • 实现 Token 同步广播机制

  • 多端登录管理

  • 设备类型标识
  • 并发登录控制

通过本文的讲解,你应该已经掌握了 Sa-Token 中 NotLoginException 异常的处理方法。在实际项目中,还需要根据具体业务场景调整 Token 策略,做好安全防护,才能构建出健壮的认证系统。

正文完
 0
评论(没有评论)