Просмотр исходного кода

fix(backend): stable_token重试失败时回退常规token接口

stable_token返回的token可能对img_sec_check已失效(42001),清除缓存后重新获取同一token仍失败,回退/cgi-bin/token获取保证全新的token

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Xiaogang Liao 2 месяцев назад
Родитель
Сommit
839890085a
1 измененных файлов с 34 добавлено и 2 удалено
  1. 34 2
      cfc-backend/src/main/java/com/etotem/cfc/service/WechatService.java

+ 34 - 2
cfc-backend/src/main/java/com/etotem/cfc/service/WechatService.java

@@ -198,7 +198,20 @@ public class WechatService implements WechatServiceInterface {
             ResponseEntity<String> response = restTemplate.postForEntity(url, requestBody.toJSONString(), String.class);
             JSONObject json = JSON.parseObject(response.getBody());
 
-            if (json.getInteger("errcode") == 0) {
+            // access_token 过期/失效(42001/40001):清除缓存后用新 token 重试一次
+            // 注意:手机号code在token校验失败时不会被消耗,可安全复用
+            int errcode = json.getInteger("errcode");
+            if (errcode == 42001 || errcode == 40001) {
+                log.warn("获取手机号 access_token 过期/失效(errcode={}),清除缓存重试", errcode);
+                invalidateAccessToken();
+                accessToken = getAccessToken();
+                url = phoneUrl + "?access_token=" + accessToken;
+                response = restTemplate.postForEntity(url, requestBody.toJSONString(), String.class);
+                json = JSON.parseObject(response.getBody());
+                errcode = json.getInteger("errcode");
+            }
+
+            if (errcode == 0) {
                 JSONObject phoneInfo = json.getJSONObject("phone_info");
                 return phoneInfo.getString("phoneNumber");
             } else {
@@ -257,6 +270,16 @@ public class WechatService implements WechatServiceInterface {
         stableTokenExpireTime = 0;
     }
 
+    /**
+     * 获取常规 access_token(fallback:当 stable_token 返回的 token 已失效时调用)
+     * /cgi-bin/token 每次返回全新 token,保证 img_sec_check 等接口可用
+     * 注意:此方法每次都会请求微信,不应在正常路径中使用,仅作为兜底
+     */
+    private String getRegularAccessToken() {
+        String token = doGetAccessToken();
+        return token;
+    }
+
     private String doGetStableAccessToken() {
         try {
             String url = "https://api.weixin.qq.com/cgi-bin/stable_token";
@@ -326,12 +349,16 @@ public class WechatService implements WechatServiceInterface {
             JSONObject json = callMsgSecCheck(getAccessToken(), content);
             int errcode = json.getInteger("errcode");
 
-            // access_token 过期/失效(42001/40001):清除缓存后用新 token 重试一次
             if (errcode == 42001 || errcode == 40001) {
                 log.warn("文本内容安全检测 access_token 过期/失效(errcode={}),清除缓存重试", errcode);
                 invalidateAccessToken();
                 json = callMsgSecCheck(getAccessToken(), content);
                 errcode = json.getInteger("errcode");
+                if (errcode == 42001 || errcode == 40001) {
+                    log.error("文本内容安全检测 stable_token 重试仍失败,回退常规token接口");
+                    json = callMsgSecCheck(getRegularAccessToken(), content);
+                    errcode = json.getInteger("errcode");
+                }
             }
 
             if (errcode == 0) {
@@ -397,6 +424,11 @@ public class WechatService implements WechatServiceInterface {
                 invalidateAccessToken();
                 json = callImgSecCheck(getAccessToken(), imageBytes);
                 errcode = json.getInteger("errcode");
+                if (errcode == 42001 || errcode == 40001) {
+                    log.error("图片内容安全检测 stable_token 重试仍失败,回退常规token接口");
+                    json = callImgSecCheck(getRegularAccessToken(), imageBytes);
+                    errcode = json.getInteger("errcode");
+                }
             }
 
             if (errcode == 0) {