feat: 添加用户登录服务及JWT认证功能
refactor: 重构实体类并添加Lombok注解 docs: 更新数据库表结构文档 style: 清理无用代码并优化格式 fix: 修复用户详情服务中的联系方式更新方法 build: 更新pom.xml配置并添加Lombok插件 test: 添加用户登录测试用例 chore: 添加开发和生产环境配置文件
This commit is contained in:
120
src/main/java/com/qf/backend/util/JwtUtils.java
Normal file
120
src/main/java/com/qf/backend/util/JwtUtils.java
Normal file
@@ -0,0 +1,120 @@
|
||||
package com.qf.backend.util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
|
||||
/**
|
||||
* JWT工具类,用于生成和验证token(JJWT 0.12.x 版本)
|
||||
* 支持 Java 17+ 和 Jakarta EE(Spring Boot 3.x)
|
||||
*/
|
||||
@Component
|
||||
public class JwtUtils {
|
||||
|
||||
@Value("${jwt.secret:default_secret_key_for_development}")
|
||||
private String secret;
|
||||
|
||||
@Value("${jwt.expiration:3600000}")
|
||||
private long expiration;
|
||||
|
||||
@Value("${jwt.token-prefix:Bearer}")
|
||||
private String tokenPrefix;
|
||||
|
||||
/**
|
||||
* 获取签名密钥
|
||||
*/
|
||||
private SecretKey getSignInKey() {
|
||||
byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
|
||||
return Keys.hmacShaKeyFor(keyBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从token中获取用户名
|
||||
*/
|
||||
public String getUsernameFromToken(String token) {
|
||||
return getClaimFromToken(token, Claims::getSubject);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从token中获取过期时间
|
||||
*/
|
||||
public Date getExpirationDateFromToken(String token) {
|
||||
return getClaimFromToken(token, Claims::getExpiration);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从token中获取指定的claim
|
||||
*/
|
||||
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
|
||||
final Claims claims = getAllClaimsFromToken(token);
|
||||
return claimsResolver.apply(claims);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token中的所有claims
|
||||
*/
|
||||
private Claims getAllClaimsFromToken(String token) {
|
||||
return Jwts.parser()
|
||||
.verifyWith(getSignInKey())
|
||||
.build()
|
||||
.parseSignedClaims(token)
|
||||
.getPayload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查token是否过期
|
||||
*/
|
||||
private Boolean isTokenExpired(String token) {
|
||||
final Date expiration = getExpirationDateFromToken(token);
|
||||
return expiration.before(new Date());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成token
|
||||
*/
|
||||
public String generateToken(UserDetails userDetails) {
|
||||
Map<String, Object> claims = new HashMap<>();
|
||||
claims.put("authorities", userDetails.getAuthorities());
|
||||
return doGenerateToken(claims, userDetails.getUsername());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成token的核心方法
|
||||
*/
|
||||
private String doGenerateToken(Map<String, Object> claims, String subject) {
|
||||
return Jwts.builder()
|
||||
.claims(claims) // 使用新的 claims() 方法
|
||||
.subject(subject) // 使用新的 subject() 方法
|
||||
.issuedAt(new Date(System.currentTimeMillis()))
|
||||
.expiration(new Date(System.currentTimeMillis() + expiration)) // 使用新的 expiration() 方法
|
||||
.signWith(getSignInKey(), Jwts.SIG.HS256) // 使用新的签名方式
|
||||
.compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证token
|
||||
*/
|
||||
public Boolean validateToken(String token, UserDetails userDetails) {
|
||||
final String username = getUsernameFromToken(token);
|
||||
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token前缀
|
||||
*/
|
||||
public String getTokenPrefix() {
|
||||
return tokenPrefix;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user