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

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 策略,做好安全防护,才能构建出健壮的认证系统。
正文完
发表至: 未分类
近一天内
