From 01ab61191b93956954b463ab4416fda6b5f960ee Mon Sep 17 00:00:00 2001
From: cl <1442464845@qq.com>
Date: 星期三, 29 四月 2026 13:48:02 +0800
Subject: [PATCH] token 改到redis

---
 rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/TokenServiceImpl.java |   97 ++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 76 insertions(+), 21 deletions(-)

diff --git a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/TokenServiceImpl.java b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/TokenServiceImpl.java
index 5a01cd9..52e97f2 100644
--- a/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/TokenServiceImpl.java
+++ b/rsf-open-api/src/main/java/com/vincent/rsf/openApi/service/impl/TokenServiceImpl.java
@@ -1,26 +1,65 @@
 package com.vincent.rsf.openApi.service.impl;
 
+import com.vincent.rsf.openApi.entity.constant.Constants;
 import com.vincent.rsf.openApi.security.service.AppAuthService;
 import com.vincent.rsf.openApi.service.TokenService;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.JwtException;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import io.jsonwebtoken.security.Keys;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
+import javax.crypto.SecretKey;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
 
+/**
+ * 瀵规帴 Token锛欽WT锛堝瘑閽ユ潵鑷厤缃紝閲嶅惎鍚庡悓涓�瀵嗛挜浠嶅彲鏍¢獙鏈繃鏈� token锛沜laims 浠呭惈 appId锛�
+ */
 @Slf4j
 @Service
 public class TokenServiceImpl implements TokenService {
 
-    private static final long EXPIRE_MS = 60 * 60 * 1000L;
+    private static final String CLAIM_APP_ID = "appId";
+
+    private final AppAuthService appAuthService;
+    private final SecretKey secretKey;
+    private final long expireMs;
 
     @Autowired
-    private AppAuthService appAuthService;
+    public TokenServiceImpl(
+            AppAuthService appAuthService,
+            @Value("${open-api.jwt.secret:}") String jwtSecret,
+            @Value("${open-api.jwt.expire-seconds:3600}") long expireSeconds) {
+        this.appAuthService = appAuthService;
+        if (!StringUtils.hasText(jwtSecret)) {
+            throw new IllegalStateException("璇烽厤缃� open-api.jwt.secret锛圚S256锛屽缓璁嚦灏� 32 瀛楃鎴栦娇鐢ㄧ幆澧冨彉閲忚鐩栵級");
+        }
+        this.secretKey = hmacSha256Key(jwtSecret.trim());
+        this.expireMs = expireSeconds * 1000L;
+    }
 
-    private final Map<String, Long> tokenExpire = new ConcurrentHashMap<>();
+    /** 鐭瓧绗︿覆鐢� SHA-256 娲剧敓 32 瀛楄妭浠ユ弧瓒� HS256 */
+    private static SecretKey hmacSha256Key(String secret) {
+        byte[] bytes = secret.getBytes(StandardCharsets.UTF_8);
+        if (bytes.length < 32) {
+            try {
+                MessageDigest md = MessageDigest.getInstance("SHA-256");
+                bytes = md.digest(bytes);
+            } catch (Exception e) {
+                throw new IllegalStateException(e);
+            }
+        }
+        return Keys.hmacShaKeyFor(bytes);
+    }
 
     @Override
     public String issueToken(String appId, String appSecret) {
@@ -30,27 +69,43 @@
         if (!appAuthService.validateApp(appId, appSecret)) {
             return null;
         }
-        String token = UUID.randomUUID().toString().replace("-", "");
-        tokenExpire.put(token, System.currentTimeMillis() + EXPIRE_MS);
-        evictExpired();
-        return token;
+        long now = System.currentTimeMillis();
+        Map<String, Object> claims = new HashMap<>();
+        claims.put(CLAIM_APP_ID, appId);
+        String compact = Jwts.builder()
+                .setClaims(claims)
+                .setIssuedAt(new Date(now))
+                .setExpiration(new Date(now + expireMs))
+                .signWith(secretKey, SignatureAlgorithm.HS256)
+                .compact();
+        return Constants.TOKEN_PREFIX + compact;
     }
 
     @Override
     public boolean validateToken(String token) {
-        if (!StringUtils.hasText(token)) {
-            return false;
-        }
-        Long expire = tokenExpire.get(token);
-        if (expire == null || System.currentTimeMillis() > expire) {
-            tokenExpire.remove(token);
-            return false;
-        }
-        return true;
+        return getAppIdIfValid(token) != null;
     }
 
-    private void evictExpired() {
-        long now = System.currentTimeMillis();
-        tokenExpire.entrySet().removeIf(e -> e.getValue() < now);
+    @Override
+    public String getAppIdIfValid(String rawToken) {
+        if (!StringUtils.hasText(rawToken)) {
+            return null;
+        }
+        try {
+            Claims claims = Jwts.parserBuilder()
+                    .setSigningKey(secretKey)
+                    .build()
+                    .parseClaimsJws(rawToken)
+                    .getBody();
+            Date exp = claims.getExpiration();
+            if (exp == null || exp.before(new Date())) {
+                return null;
+            }
+            Object appId = claims.get(CLAIM_APP_ID);
+            return appId != null ? appId.toString() : null;
+        } catch (JwtException e) {
+            log.debug("JWT 鏍¢獙澶辫触: {}", e.getMessage());
+            return null;
+        }
     }
 }

--
Gitblit v1.9.1