fix(qrLogin): 优化小程序码Token错误处理与缓存清理
- 新增access_token对应Redis键,保持与WxService一致 - 获取access_token失败时添加缓存清理操作 - 生成小程序码API返回token相关错误时清理缓存 - 异常捕获时也进行access_token缓存清理,防止token问题 - 增加判断token相关错误码的方法,明确常见微信API错误码 - 实现清理access_token缓存方法,包含异常日志处理
This commit is contained in:
@@ -126,11 +126,16 @@ public class QrLoginServiceImpl implements QrLoginService {
|
|||||||
* @return 小程序码图片Base64字符串
|
* @return 小程序码图片Base64字符串
|
||||||
*/
|
*/
|
||||||
private String generateMiniprogramQrCode(String token, Integer tenantId) {
|
private String generateMiniprogramQrCode(String token, Integer tenantId) {
|
||||||
|
// 构建 access_token 的 Redis key(与 WxService 保持一致)
|
||||||
|
String accessTokenKey = "WX_ACCESS_TOKEN:" + (tenantId != null ? tenantId : 10048);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 获取小程序access_token
|
// 获取小程序access_token
|
||||||
String accessToken = wxService.getAccessToken(tenantId);
|
String accessToken = wxService.getAccessToken(tenantId);
|
||||||
if (StrUtil.isBlank(accessToken)) {
|
if (StrUtil.isBlank(accessToken)) {
|
||||||
log.warn("获取小程序access_token失败,跳过生成小程序码");
|
log.warn("获取小程序access_token失败,跳过生成小程序码,将清理缓存");
|
||||||
|
// 获取失败时清理缓存,下次会重新获取
|
||||||
|
clearAccessTokenCache(accessTokenKey, tenantId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +171,18 @@ public class QrLoginServiceImpl implements QrLoginService {
|
|||||||
// 检查是否返回JSON错误(微信API错误时会返回JSON)
|
// 检查是否返回JSON错误(微信API错误时会返回JSON)
|
||||||
if (imageBytes.length < 100 && new String(imageBytes).startsWith("{")) {
|
if (imageBytes.length < 100 && new String(imageBytes).startsWith("{")) {
|
||||||
JSONObject errorResult = JSON.parseObject(new String(imageBytes));
|
JSONObject errorResult = JSON.parseObject(new String(imageBytes));
|
||||||
log.error("生成小程序码API返回错误: {}", errorResult);
|
Integer errCode = errorResult.getInteger("errcode");
|
||||||
|
String errMsg = errorResult.getString("errmsg");
|
||||||
|
|
||||||
|
// 判断是否是 token 相关错误,需要清理缓存
|
||||||
|
boolean shouldClearCache = isTokenRelatedError(errCode, errMsg);
|
||||||
|
|
||||||
|
if (shouldClearCache) {
|
||||||
|
log.error("生成小程序码API返回token相关错误[{}:{}],将清理缓存", errCode, errMsg);
|
||||||
|
clearAccessTokenCache(accessTokenKey, tenantId);
|
||||||
|
} else {
|
||||||
|
log.error("生成小程序码API返回错误[{}:{}],不清理缓存", errCode, errMsg);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,10 +192,55 @@ public class QrLoginServiceImpl implements QrLoginService {
|
|||||||
return "data:image/png;base64," + base64Image;
|
return "data:image/png;base64," + base64Image;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("生成小程序码异常: {}", e.getMessage(), e);
|
log.error("生成小程序码异常: {}", e.getMessage(), e);
|
||||||
|
// 异常时也清理缓存,以防是 token 问题
|
||||||
|
clearAccessTokenCache(accessTokenKey, tenantId);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是 token 相关的错误码,需要清理缓存
|
||||||
|
* 常见微信 API 错误码:
|
||||||
|
* - 40001: 获取access_token时AppSecret错误
|
||||||
|
* - 40013: appid无效
|
||||||
|
* - 40125: appsecret无效
|
||||||
|
* - 42001: access_token超时
|
||||||
|
* - 42002: refresh_token超时
|
||||||
|
* - 42003: code超时
|
||||||
|
* - 44002: post body太长
|
||||||
|
* - 44003: 图片太大
|
||||||
|
* - 41002: appid不正确
|
||||||
|
* - 41008: 缺少access_token参数
|
||||||
|
*/
|
||||||
|
private boolean isTokenRelatedError(Integer errCode, String errMsg) {
|
||||||
|
if (errCode == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// token 相关错误码
|
||||||
|
return errCode == 40001 // AppSecret错误
|
||||||
|
|| errCode == 40013 // appid无效
|
||||||
|
|| errCode == 40125 // appsecret无效
|
||||||
|
|| errCode == 42001 // access_token超时
|
||||||
|
|| errCode == 42002 // refresh_token超时
|
||||||
|
|| errCode == 42003 // code超时
|
||||||
|
|| errCode == 41002 // appid不正确
|
||||||
|
|| errCode == 41008 // 缺少access_token参数
|
||||||
|
|| errCode == 40014 // 不合法的access_token
|
||||||
|
|| errCode == 40097; // invalid page
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理 access_token 缓存
|
||||||
|
*/
|
||||||
|
private void clearAccessTokenCache(String accessTokenKey, Integer tenantId) {
|
||||||
|
try {
|
||||||
|
redisUtil.delete(accessTokenKey);
|
||||||
|
log.info("清理微信access_token缓存[{}], tenantId={}", accessTokenKey, tenantId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("清理access_token缓存失败: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QrLoginStatusResponse checkQrLoginStatus(String token) {
|
public QrLoginStatusResponse checkQrLoginStatus(String token) {
|
||||||
if (StrUtil.isBlank(token)) {
|
if (StrUtil.isBlank(token)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user