SpringBoot + JWT 打造无状态登录系统,让你的应用更安全高效
还在为Session共享烦恼?每次集群部署都要头疼用户状态同步?传统Cookie+Session模式在分布式场景下越来越力不从心?本文将手把手带你用SpringBoot+JWT实现无状态登录,轻松解决分布式认证难题,代码可直接移植到你的项目!
一、为什么选择JWT?传统Session的致命缺陷
传统Session的问题:
- 服务端存储压力大,用户量激增时内存崩溃
- 集群环境下需要Session共享,增加架构复杂度
- CSRF攻击风险高,安全性难以保障
JWT优势:
- 无状态:Token自包含用户信息,服务端无需存储
- 跨域支持:轻松解决分布式系统认证
- 安全性强:数字签名防篡改,可选择加密算法
二、JWT核心原理图解
Token组成:
Header(算法类型)
Payload(携带数据)
Signature(签名哈希)
Base64编码后组合:xxxxx.yyyyy.zzzzz
工作流程:
- 用户登录成功后生成JWT
- 客户端存储Token(LocalStorage/Header)
- 每次请求携带Token进行身份验证
三、SpringBoot整合JWT实战(代码可复用)
1 添加依赖
xml
<!-- JWT支持 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2 编写JWT工具类
java
public class JwtUtils {
private static final String SECRET_KEY = "your-256-bit-secret"; // 实际项目从配置读取
private static final long EXPIRATION = 86400000; // 24小时
// 生成Token
public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
// 解析验证Token
public static Claims parseToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
}
3 实现登录拦截器
java
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
String token = request.getHeader("Authorization");
try {
Claims claims = JwtUtils.parseToken(token);
request.setAttribute("username", claims.getSubject());
return true;
} catch (Exception e) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return false;
}
}
}
4 配置拦截规则
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JwtInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api/login");
}
}
5 编写登录接口
java
@RestController
@RequestMapping("/api")
public class AuthController {
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
// 1. 验证用户名密码(示例代码,实际需查数据库)
if(!"admin".equals(request.getUsername()) || !"123456".equals(request.getPassword())){
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
// 2. 生成Token
String token = JwtUtils.generateToken(request.getUsername());
return ResponseEntity.ok().header("Authorization", token).build();
}
}
四、接口测试(Postman实战演示)
登录请求:
bash
POST /api/login
Body: {"username":"admin","password":"123456"}
Response Header中获取Authorization
访问受保护接口:
bash
GET /api/userInfo
Header添加:Authorization: Bearer <your_token>
五、生产环境优化建议
- 密钥管理:使用HS512算法,密钥存储在配置中心
- Token刷新:通过Refresh Token机制延长有效期
- 黑名单处理:实现登出功能时记录失效Token
- 安全增强:结合Spring Security做权限控制
结语
通过本文,你已经掌握了SpringBoot整合JWT的核心方法!无状态认证不仅能提升系统性能,更为微服务架构打下坚实基础。如果对你有帮助,欢迎:
点赞支持 | 收藏备用 | 关注获取更多技术干货