修改JWT令牌相关
> 修改被波及的GetTokenUserId
> 创建DTO类统一使用
> 修改JWTEngine
> 修改接口/me, 返回用户id数据.
> 修改接口/me的responseDto
Change-Id: I0064eed4ff7f592b3afefe0f4744f797245353f0
diff --git a/src/main/java/edu/bjtu/groupone/backend/api/UserController.java b/src/main/java/edu/bjtu/groupone/backend/api/UserController.java
index c4ebbec..620e885 100644
--- a/src/main/java/edu/bjtu/groupone/backend/api/UserController.java
+++ b/src/main/java/edu/bjtu/groupone/backend/api/UserController.java
@@ -71,11 +71,10 @@
u.setPassword(request.getPassword());
User user = userService.login(u);
if (user != null) {
- var payload = java.util.Map.<String, Object>of(
- "id", user.getUserId(),
- "username", user.getUsername(),
- "email", user.getEmail()
- );
+ var payload = new ClaimsDTO();
+ payload.setEmail(user.getEmail());
+ payload.setUsername(user.getUsername());
+ payload.setUserid(user.getUserId());
String token = JwtUtils.generateJwt(payload);
return Result.success(token);
}
@@ -278,19 +277,20 @@
)
}
)
- @GetMapping("/api/me")
+
+ @GetMapping("/me")
public Result<UserInfoResponse> me(@Parameter(in = ParameterIn.HEADER, description = "JWT认证令牌") @RequestHeader("token") String token) {
- var claims = JwtUtils.parseJwt(token);
- if (claims == null) {
- return Result.error("无效的 token");
+ ClaimsDTO claims;
+ try {
+ claims = JwtUtils.parseJwt(token); // 解析JWT
+ } catch (RuntimeException e) {
+ return Result.error("无效的 token: " + e.getMessage()); // 处理 JWT 异常
}
- UserInfoResponse info = new UserInfoResponse(
- (String) claims.get("username"),
- token
- );
+ UserInfoResponse info = new UserInfoResponse(claims.getUsername(), claims.getUserid());
return Result.success(info);
}
+
@DeleteMapping("/{userId}")
@Operation(summary = "删除用户")
public Result<String> deleteUser(@PathVariable int userId) {
@@ -368,25 +368,20 @@
@Parameter(in = ParameterIn.HEADER, description = "旧的 JWT 令牌", required = true)
@RequestHeader("token") String oldToken
) {
- Claims claims;
+ ClaimsDTO claims;
try {
// 尝试解析;如果尚未过期,parseJwt 会返回 Claims
claims = JwtUtils.parseJwt(oldToken);
} catch (ExpiredJwtException ex) {
// 如果已过期,则从异常中获取过期前的 Claims
- claims = ex.getClaims();
+ claims = new ClaimsDTO(ex.getClaims());
} catch (Exception ex) {
// 其它解析错误(签名无效等)
return Result.error("无效的 token");
}
// 从原有的 Claims 中提取用户信息,重新生成新的 token
- var payload = java.util.Map.<String, Object>of(
- "id", claims.get("id"),
- "username", claims.get("username"),
- "email", claims.get("email")
- );
- String newToken = JwtUtils.generateJwt(payload);
+ String newToken = JwtUtils.generateJwt(claims);
return Result.success(newToken);
}
@Operation(
diff --git a/src/main/java/edu/bjtu/groupone/backend/domain/dto/ClaimsDTO.java b/src/main/java/edu/bjtu/groupone/backend/domain/dto/ClaimsDTO.java
new file mode 100644
index 0000000..1fddd4f
--- /dev/null
+++ b/src/main/java/edu/bjtu/groupone/backend/domain/dto/ClaimsDTO.java
@@ -0,0 +1,29 @@
+package edu.bjtu.groupone.backend.domain.dto;
+
+import io.jsonwebtoken.Claims;
+import io.swagger.models.auth.In;
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class ClaimsDTO {
+ // Getters 和 Setters
+ private int userid;
+ private String username;
+ private String email;
+
+ public ClaimsDTO() {
+ this.userid = 0;
+ this.username = "";
+ this.email = "";
+ }
+
+ public ClaimsDTO(Claims claims) {
+ // 将 claims 映射到 ClaimsDTO
+ this.setUserid(((Number) claims.get("userid")).intValue()); // 确保 userid 是 Long 类型
+ this.setUsername((String) claims.get("username"));
+ this.setEmail((String) claims.get("email"));
+ }
+}
+
diff --git a/src/main/java/edu/bjtu/groupone/backend/domain/dto/UserInfoResponse.java b/src/main/java/edu/bjtu/groupone/backend/domain/dto/UserInfoResponse.java
index 99ab656..64960b9 100644
--- a/src/main/java/edu/bjtu/groupone/backend/domain/dto/UserInfoResponse.java
+++ b/src/main/java/edu/bjtu/groupone/backend/domain/dto/UserInfoResponse.java
@@ -6,15 +6,14 @@
@Data
@Schema(description = "用户信息响应")
public class UserInfoResponse {
-
+ @Schema(description = "用户id", example = "1")
+ private int userid;
@Schema(description = "用户名", example = "john_doe")
private String username;
- @Schema(description = "JWT认证令牌", example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
- private String token;
- public UserInfoResponse(String username, String token) {
+ public UserInfoResponse(String username, int userid) {
this.username = username;
- this.token = token;
+ this.userid = userid;
}
}
\ No newline at end of file
diff --git a/src/main/java/edu/bjtu/groupone/backend/utils/GetTokenUserId.java b/src/main/java/edu/bjtu/groupone/backend/utils/GetTokenUserId.java
index 63dda65..3f803b3 100644
--- a/src/main/java/edu/bjtu/groupone/backend/utils/GetTokenUserId.java
+++ b/src/main/java/edu/bjtu/groupone/backend/utils/GetTokenUserId.java
@@ -1,5 +1,6 @@
package edu.bjtu.groupone.backend.utils;
+import edu.bjtu.groupone.backend.domain.dto.ClaimsDTO;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
@@ -9,7 +10,7 @@
String token = request.getHeader("token");
// 解析 JWT Token,获取用户 ID
String jwt = token.substring(7); // 去掉 'Bearer ' 前缀
- Claims claims = JwtUtils.parseJwt(jwt); // 从 JWT 中获取用户 ID
- return claims.get("id").toString();
+ ClaimsDTO claims = JwtUtils.parseJwt(jwt); // 从 JWT 中获取用户 ID
+ return Integer.toString(claims.getUserid());
}
}
diff --git a/src/main/java/edu/bjtu/groupone/backend/utils/JwtUtils.java b/src/main/java/edu/bjtu/groupone/backend/utils/JwtUtils.java
index 45e736b..b2d2228 100644
--- a/src/main/java/edu/bjtu/groupone/backend/utils/JwtUtils.java
+++ b/src/main/java/edu/bjtu/groupone/backend/utils/JwtUtils.java
@@ -1,36 +1,47 @@
package edu.bjtu.groupone.backend.utils;
+import edu.bjtu.groupone.backend.domain.dto.ClaimsDTO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.ExpiredJwtException;
+import io.jsonwebtoken.MalformedJwtException;
+import io.jsonwebtoken.SignatureException;
+import io.jsonwebtoken.UnsupportedJwtException;
import java.util.Date;
+import java.util.HashMap;
import java.util.Map;
public class JwtUtils {
+ private static final String SECRET_KEY = "Bjtu";
-
-
- // 生成JWT// 生成JWT
- public static String generateJwt(Map<String,Object> claims) {
-
- String jwt = Jwts.builder().
- addClaims(claims)
- .signWith(io.jsonwebtoken.SignatureAlgorithm.HS256, "Bjtu")
- .setExpiration(new Date(System.currentTimeMillis() + 43200000L))
- .compact();
-
-
- return jwt;
-
-
- }
-
- public static Claims parseJwt(String jwt) {
-
- return Jwts.parser()
- .setSigningKey("Bjtu")
+ // 解析JWT并映射到 ClaimsDTO
+ public static ClaimsDTO parseJwt(String jwt) {
+ Claims claims = Jwts.parser()
+ .setSigningKey(SECRET_KEY)
.parseClaimsJws(jwt)
.getBody();
+ return new ClaimsDTO(claims);
}
-}
\ No newline at end of file
+ // 默认过期时间为 2 小时(7200000 毫秒)
+ private static final long DEFAULT_EXPIRATION = 7200000L;
+ // 生成JWT
+ public static String generateJwt(ClaimsDTO claimsDTO, long expirationMillis) {
+ Map<String, Object> claims = new HashMap<>();
+ claims.put("userid", claimsDTO.getUserid());
+ claims.put("username", claimsDTO.getUsername());
+ claims.put("email", claimsDTO.getEmail());
+
+ return Jwts.builder()
+ .addClaims(claims)
+ .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
+ .setExpiration(new Date(System.currentTimeMillis() + expirationMillis))
+ .compact();
+ }
+
+ public static String generateJwt(ClaimsDTO claims) {
+ return generateJwt(claims, DEFAULT_EXPIRATION);
+ }
+}