From fe962d501a82804a87f1dab8cec951fb16fba61c Mon Sep 17 00:00:00 2001 From: msksbr515 Date: Sat, 23 May 2026 15:41:31 +0800 Subject: [PATCH] feat(auth): embed userId in JWT token and expose via request attribute - add userId parameter to generateToken and include it in JWT claims - extract userId from token in JwtPopulateFilter and set as request attribute - inject IpExtractor and JwtUtils into AuthController for token generation --- .../com/msksbr/bookmgr/config/JwtPopulateFilter.kt | 3 ++- src/main/kotlin/com/msksbr/bookmgr/config/JwtUtils.kt | 5 +++-- .../com/msksbr/bookmgr/controller/AuthController.kt | 9 +++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/com/msksbr/bookmgr/config/JwtPopulateFilter.kt b/src/main/kotlin/com/msksbr/bookmgr/config/JwtPopulateFilter.kt index c068746..4d2dd51 100644 --- a/src/main/kotlin/com/msksbr/bookmgr/config/JwtPopulateFilter.kt +++ b/src/main/kotlin/com/msksbr/bookmgr/config/JwtPopulateFilter.kt @@ -29,7 +29,8 @@ class JwtPopulateFilter( if (claims != null) { request.setAttribute("username", claims.subject) request.setAttribute("role", claims.get("role", String::class.java)) - log.debug("[JWT] identified: user={}, role={}", claims.subject, claims.get("role", String::class.java)) + request.setAttribute("userId", claims.get("userId", Long::class.java)) + log.debug("[JWT] identified: user={}, role={}, userId={}", claims.subject, claims.get("role", String::class.java), claims.get("userId", Long::class.java)) } } filterChain.doFilter(request, response) diff --git a/src/main/kotlin/com/msksbr/bookmgr/config/JwtUtils.kt b/src/main/kotlin/com/msksbr/bookmgr/config/JwtUtils.kt index 5d9badc..e9879c4 100644 --- a/src/main/kotlin/com/msksbr/bookmgr/config/JwtUtils.kt +++ b/src/main/kotlin/com/msksbr/bookmgr/config/JwtUtils.kt @@ -54,6 +54,7 @@ class JwtUtils( * 签发 JWT token * @param username 用户名,写入 sub(subject)字段 * @param role 角色,写入自定义 claims 的 role 字段 + * @param userId 用户 ID,写入自定义 claims 的 userId 字段 * @return 签发的 JWT 字符串 * * token 结构(由 jjwt 库生成): @@ -61,8 +62,8 @@ class JwtUtils( * Payload: { "sub": "admin", "role": "admin", "iat": ..., "exp": ... } * Signature: HMAC-SHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secretKey) */ - fun generateToken(username: String, role: String): String { - val claims = Jwts.claims().add("role", role).build() + fun generateToken(username: String, role: String, userId: Long): String { + val claims = Jwts.claims().add("role", role).add("userId", userId).build() val token = Jwts.builder().claims(claims).subject(username) .issuedAt(Date()).expiration( Date( diff --git a/src/main/kotlin/com/msksbr/bookmgr/controller/AuthController.kt b/src/main/kotlin/com/msksbr/bookmgr/controller/AuthController.kt index aca6c52..634e472 100644 --- a/src/main/kotlin/com/msksbr/bookmgr/controller/AuthController.kt +++ b/src/main/kotlin/com/msksbr/bookmgr/controller/AuthController.kt @@ -8,11 +8,7 @@ import com.msksbr.bookmgr.service.AuthService import com.msksbr.bookmgr.template.Result import jakarta.servlet.http.HttpServletRequest import jakarta.validation.Valid -import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.RequestAttribute -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController +import org.springframework.web.bind.annotation.* /* * 认证接口 @@ -52,11 +48,12 @@ class AuthController( val user = authService.login(loginDTO) return if (user != null) { // 登录成功,签发 JWT - val token = jwtUtils.generateToken(user.username, user.role) + val token = jwtUtils.generateToken(user.username, user.role, user.id!!) log.info("[Auth] login success: user={}", user.username) Result.success( mapOf( "token" to token, + "id" to user.id, "username" to user.username, "role" to user.role )