refactor(wxOfficial): 优化公众号配置和access_token获取逻辑
- 增加SettingService和WxService注入,提高配置获取灵活性 - 将access_token获取方法重载,支持按租户动态读取 - 新增getOfficialToken、getOfficialEncodingAESKey、getOfficialAppId方法,从系统设置读取配置 - 解密消息时改用动态获取的token、EncodingAESKey和AppId - 微信用户信息请求改为支持按租户获取access_token - access_token获取失败时添加异常日志并回退到兼容逻辑 - 移除硬编码逻辑,增强配置读取的可扩展性与健壮性
This commit is contained in:
@@ -24,10 +24,12 @@ import com.gxwebsoft.common.system.entity.*;
|
||||
import com.gxwebsoft.common.system.param.RoleParam;
|
||||
import com.gxwebsoft.common.system.param.UserParam;
|
||||
import com.gxwebsoft.common.system.service.RoleService;
|
||||
import com.gxwebsoft.common.system.service.SettingService;
|
||||
import com.gxwebsoft.common.system.service.UserOauthService;
|
||||
import com.gxwebsoft.common.system.service.UserRoleService;
|
||||
import com.gxwebsoft.common.system.service.UserService;
|
||||
import com.gxwebsoft.common.system.service.UserSyncService;
|
||||
import com.gxwebsoft.common.system.service.WxService;
|
||||
import com.gxwebsoft.common.system.vo.WxOfficialButton;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -88,6 +90,10 @@ public class WxOfficialController extends BaseController {
|
||||
@Resource
|
||||
private UserOauthService userOauthService;
|
||||
@Resource
|
||||
private SettingService settingService;
|
||||
@Resource
|
||||
private WxService wxService;
|
||||
@Resource
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Operation(summary = "验证微信服务器")
|
||||
@@ -98,7 +104,7 @@ public class WxOfficialController extends BaseController {
|
||||
if (tenantId == null) {
|
||||
return null;
|
||||
}
|
||||
String token = TOKEN;
|
||||
String token = getOfficialToken();
|
||||
String[] array = new String[]{token, timestamp, nonce};
|
||||
// 将token、timestamp、nonce三个参数进行字典序排序
|
||||
Arrays.sort(array);
|
||||
@@ -133,7 +139,7 @@ public class WxOfficialController extends BaseController {
|
||||
// 如果有加密参数,进行解密
|
||||
if (StrUtil.isNotBlank(msg_signature) && StrUtil.isNotBlank(xmlData) && xmlData.contains("Encrypt")) {
|
||||
try {
|
||||
WXBizJsonMsgCrypt crypt = new WXBizJsonMsgCrypt(TOKEN, ENCODING_AES_KEY, "");
|
||||
WXBizJsonMsgCrypt crypt = new WXBizJsonMsgCrypt(getOfficialToken(), getOfficialEncodingAESKey(), getOfficialAppId(tenantId));
|
||||
xmlData = crypt.DecryptMsg(msg_signature, timestamp, nonce, xmlData);
|
||||
System.out.println("解密后xmlData = " + xmlData);
|
||||
} catch (Exception e) {
|
||||
@@ -189,7 +195,7 @@ public class WxOfficialController extends BaseController {
|
||||
// 获取用户信息
|
||||
if (StrUtil.isNotBlank(openId)) {
|
||||
// 获取用户基本信息(UnionID机制)
|
||||
final String userStr = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + getAccessToken() + "&openid=" + openId + "&lang=zh_CN");
|
||||
final String userStr = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + getAccessToken(tenantId) + "&openid=" + openId + "&lang=zh_CN");
|
||||
final JSONObject jsonObject = JSONObject.parseObject(userStr);
|
||||
final String unionid = jsonObject.getString("unionid");
|
||||
final String subscribe = jsonObject.getString("subscribe");
|
||||
@@ -451,30 +457,65 @@ public class WxOfficialController extends BaseController {
|
||||
|
||||
// 调用接口凭证
|
||||
private String getAccessToken() {
|
||||
return getAccessToken(null);
|
||||
}
|
||||
|
||||
private String getAccessToken(Integer tenantId) {
|
||||
try {
|
||||
return wxService.getOfficialAccessToken(tenantId);
|
||||
} catch (Exception ex) {
|
||||
log.warn("从系统设置获取公众号access_token失败,回退到兼容逻辑: {}", ex.getMessage());
|
||||
}
|
||||
|
||||
String key = MP_OFFICIAL.concat(":access_token:5");
|
||||
// 从缓存获取access_token
|
||||
String value = redisUtil.get(key);
|
||||
if (value != null) {
|
||||
// 解析access_token
|
||||
JSONObject response = JSON.parseObject(value);
|
||||
return response.getString("access_token");
|
||||
}
|
||||
// 微信获取凭证接口https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
|
||||
|
||||
String apiUrl = "https://api.weixin.qq.com/cgi-bin/token";
|
||||
// 组装url参数
|
||||
String url = apiUrl.concat("?grant_type=client_credential").concat("&appid=").concat(appid).concat("&secret=").concat(secret);
|
||||
// 执行get请求
|
||||
String result = HttpUtil.get(url);
|
||||
// 解析access_token
|
||||
JSONObject response = JSON.parseObject(result);
|
||||
if (response.getString("access_token") != null) {
|
||||
// 存入缓存
|
||||
redisUtil.set(key, result, 7000L, TimeUnit.SECONDS);
|
||||
return response.getString("access_token");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String getOfficialToken() {
|
||||
try {
|
||||
JSONObject config = settingService.getBySettingKey("wx-official");
|
||||
String token = config.getString("token");
|
||||
return StrUtil.isNotBlank(token) ? token : TOKEN;
|
||||
} catch (Exception ex) {
|
||||
log.warn("读取公众号token配置失败,回退到硬编码值: {}", ex.getMessage());
|
||||
return TOKEN;
|
||||
}
|
||||
}
|
||||
|
||||
private String getOfficialEncodingAESKey() {
|
||||
try {
|
||||
JSONObject config = settingService.getBySettingKey("wx-official");
|
||||
String encodingAESKey = config.getString("encodingAESKey");
|
||||
return StrUtil.isNotBlank(encodingAESKey) ? encodingAESKey : ENCODING_AES_KEY;
|
||||
} catch (Exception ex) {
|
||||
log.warn("读取公众号EncodingAESKey配置失败,回退到硬编码值: {}", ex.getMessage());
|
||||
return ENCODING_AES_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
private String getOfficialAppId(Integer tenantId) {
|
||||
try {
|
||||
return wxService.getOfficialAppId(tenantId);
|
||||
} catch (Exception ex) {
|
||||
log.warn("读取公众号AppId配置失败,回退到硬编码值: {}", ex.getMessage());
|
||||
return appid;
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "创建公众号菜单接口")
|
||||
@PostMapping("/createMenu")
|
||||
public ApiResult<?> createMenu() {
|
||||
|
||||
Reference in New Issue
Block a user