SpringBoot急速上手JWT
application.properties:
jwt.secret=密钥串
jwt.access-token-expiration=1800000访问 //token过期时间 单位: 秒
jwt.refresh-token-expiration=604800000 //刷新token过期时间 单位:秒JwtUtil.java:
@Component
public class JwtUtil {
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.access-token-expiration}")
private long accessExpiration;
@Value("${jwt.refresh-token-expiration}")
private long refreshExpiration;
// 生成 Access Token
public String generateAccessToken(String username) {
return buildToken(username, accessExpiration);
}
// 生成 Refresh Token
public String generateRefreshToken(String username) {
return buildToken(username, refreshExpiration);
}
// 从 Token 取用户名
public String getUsernameFromToken(String token) {
Claims claims = Jwts.parser()
.verifyWith(getSignKey())
.build()
.parseSignedClaims(token)
.getPayload();
return claims.getSubject();
}
// 验证 Token 是否有效
public boolean validateToken(String token) {
try {
Jwts.parser()
.verifyWith(getSignKey())
.build()
.parseSignedClaims(token);
return true;
} catch (Exception e) {
return false;
}
}
// 内部方法:构建 Token
private String buildToken(String username, long expiration) {
return Jwts.builder()
.subject(username)
.issuedAt(new Date())
.expiration(new Date(System.currentTimeMillis() + expiration))
.signWith(getSignKey())
.compact();
}
// 获取签名密钥
private SecretKey getSignKey() {
return Keys.hmacShaKeyFor(secret.getBytes());
}
}JwtInterceptor.java:
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
private JwtUtil jwtUtil;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 1. 从 Header 取 Token
String token = request.getHeader("Authorization");
// 2. 没有 Token
if (token == null || !token.startsWith("Bearer ")) {
response.setStatus(401);
return false;
}
// 3. 去掉 "Bearer " 前缀
token = token.substring(7);
// 4. 验证 Token
if (!jwtUtil.validateToken(token)) {
response.setStatus(401);
return false;
}
// 5. 验证通过,放行
return true;
}
WebConfig.java:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private JwtInterceptor jwtInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/api/**") // 拦截所有 /api/**
.excludePathPatterns("/api/auth/login"); // 排除登录接口
}
}LoginController.java
@Controller
@RequestMapping("/api/auth")
public class LoginController {
@Autowired
private UserRepository userRepository;
@Autowired
private JwtUtil jwtUtil;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
//查找用户
User user = userRepository.findByUsername(request.getUsername())
.orElse(null);
//验证密码
if(user == null || user.getPassword().equals(request.getUsername())){
return ResponseEntity.status(401).body("账号或密码错误");
}
//生成双 Token
String accessToken = jwtUtil.generateAccessToken(user.getUsername());
String refreshToken = jwtUtil.generateRefreshToken(user.getUsername());
//返回
return ResponseEntity.ok(Map.of(
"accessToken", accessToken,
"refreshToken", refreshToken
));
}
}SpringBoot急速上手JWT
https://blog.oceanparadise.cn/archives/Zwp2XGaW
评论