1、授权事件接收 URL
此处要注意5个参数和1个xml响应体,其中xml要注意先Unicode解码一下,然后需要再按照指定格式解析出来encrypt,然后注意wxBizMsgCrypt.decryptMsg的最后一个参数是经过格式转换的,不是原来微信直接返回的xml,此处是关键,很多博主的代码中这一块被工具类代码隐藏了。具体代码如下:
@ApiOperation("授权事件接收URL")
@RequestMapping(value = "/receiveAuth", method ={RequestMethod.POST, RequestMethod.GET})
public Object receiveAuth(@RequestBody String postData,
@RequestParam(value = "signature", required = false) String signature,
@RequestParam(value = "timestamp", required = false) String timeStamp,
@RequestParam(value = "nonce", required = false) String nonce,
@RequestParam(value = "encrypt_type", required = false) String encryptType,
@RequestParam(value = "msg_signature", required = false) String msgSignature) {
try {
//从XML中获取<Encrypt></Encrypt>标签内的密文文本
if (postData.endsWith("\\n")) {
postData = postData.substring(0, postData.length() -2);
}
postData = UnicodeUtil.toString(postData);
Document document = XmlUtil.readXML(postData);
NodeList nodeList = document.getElementsByTagName("Encrypt");
String encrypt = nodeList.item(0).getTextContent();
log.info("Encrypt:" + encrypt);
//格式化密文文本,否则没有<ToUserName>标签,会解密失败,参考官方的加解密代码JAVA版本
String format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>";
String fromXML = String.format(format, encrypt);
String msg; //解密后的明文
if(StrUtil.isEmpty(encrypt)) {
msg = fromXML;
} else {
WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(Token, EncodingAESKey, appId);
// 解密消息
msg = wxBizMsgCrypt.decryptMsg(msgSignature, timeStamp, nonce, fromXML);
}
log.info("解密后的明文:" + msg);
//将XML格式字符串转为Map类型
Document resultDocument = XmlUtil.readXML(msg);
NodeList infoTypeNodeList = resultDocument.getElementsByTagName("InfoType");
String infoType = infoTypeNodeList.item(0).getTextContent();
switch (infoType) {
case "component_verify_ticket":
NodeList ticketNodeList = resultDocument.getElementsByTagName("ComponentVerifyTicket");
String componentVerifyTicket = ticketNodeList.item(0).getTextContent();
Jedis jedis = null;
try {
jedis = RedisUtil.getWeChatJedis();
jedis.set(MiniProgramComponentVerifyTicket, componentVerifyTicket);
jedis.expire(MiniProgramComponentVerifyTicket, 60*60*12);
} finally {
jedis.close();
}
log.info("ComponentVerifyTicket成功更新:{}", componentVerifyTicket);
break;
default:
break;
}
} catch (Exception e) {
log.error(e.getMessage());
}
return "success";
}
2、消息与事件接收URL,此处只是简单的实现了接口,没有具体做处理
@ApiOperation("消息与事件接收URL")
@RequestMapping(value = "/appid/callback", method ={RequestMethod.POST, RequestMethod.GET})
public Object callback(@RequestBody String xml,
@RequestParam(value = "signature", required = false) String signature,
@RequestParam(value = "timestamp", required = false) String timeStamp,
@RequestParam(value = "nonce", required = false) String nonce,
@RequestParam(value = "encrypt_type", required = false) String encryptType,
@RequestParam(value = "msg_signature", required = false) String msgSignature) throws Exception {
return "success";
}
3、其他接口的实现,要注意2点:
一、参数component_access_token是放在请求链接上的
二、请求体是json转换的字符串,不是json。
相关示例代码:
public String getComponentAccessToken() {
String componentAccessToken = null;
Jedis jedis = null;
try {
jedis = RedisUtil.getWeChatJedis();
componentAccessToken = jedis.get(ComponentAccessToken);
if (componentAccessToken != null) {
return componentAccessToken;
}
Map<String, Object> param = new HashMap<>();
param.put("component_appid", ComponentAppid);
param.put("component_appsecret", ComponentAppsecret);
String componentVerifyTicket = jedis.get(MiniProgramComponentVerifyTicket);
param.put("component_verify_ticket", componentVerifyTicket);
System.out.println(JSONUtil.toJsonStr(param));
String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/component/api_component_token", JSONUtil.toJsonStr(param));
log.info("微信第三方平台接口:获取令牌,返回结果:{}", post);
JSONObject jsonObject = JSONUtil.parseObj(post);
Object token = jsonObject.get("component_access_token");
if (token != null) {
jedis.set(ComponentAccessToken, (String) token);
jedis.expire(ComponentAccessToken, 7100);
componentAccessToken = (String) token;
log.info("重新获取component_access_token并放Redis中缓存成功:", token);
}
} catch (Exception e) {
log.error("获取component_access_token失败:", e);
} finally {
jedis.close();
}
return componentAccessToken;
}
/**
* 获取预授权码
* https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/ThirdParty/token/pre_auth_code.html
* @return
*/
public ResultDto getPreAuthCode() {
String componentAccessToken = getComponentAccessToken();
Map<String, Object> param = new HashMap<>();
param.put("component_appid", ComponentAppid);
String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=" + componentAccessToken, JSONUtil.toJsonStr(param));
log.info("微信第三方平台接口:获取预授权码,返回结果:{}", post);
JSONObject jsonObject = JSONUtil.parseObj(post);
if (jsonObject.get("pre_auth_code") != null) {
String preAuthCode = (String) jsonObject.get("pre_auth_code");
log.info("获取component_access_token成功:", preAuthCode);
return new ResultDto(CodeEnum.SUCCESS, preAuthCode);
} else {
return new ResultDto(CodeEnum.ERROR_WE_CHAT, post);
}
}
/**
* 使用授权码获取授权信息
* https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/ThirdParty/token/authorization_info.html
* @param req
* @return
*/
public ResultDto getAuthorizationInfo(GetAuthorizationInfoReq req) {
String componentAccessToken = getComponentAccessToken();
Map<String, Object> param = new HashMap<>();
param.put("component_appid", ComponentAppid);
param.put("authorization_code", req.getAuthorizationCode());
String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=" + componentAccessToken, JSONUtil.toJsonStr(param));
log.info("微信第三方平台接口:使用授权码获取授权信息,返回结果:{}", post);
JSONObject jsonObject = JSONUtil.parseObj(post);
return new ResultDto(CodeEnum.SUCCESS, jsonObject);
}
public ResultDto getOrRefreshToken(GetOrRefreshTokenReq req) {
String componentAccessToken = getComponentAccessToken();
Map<String, Object> param = new HashMap<>();
param.put("component_appid", ComponentAppid);
param.put("authorizer_appid", req.getAuthorizerAppid());
param.put("authorizer_refresh_token", req.getAuthorizerRefreshToken());
String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=" + componentAccessToken, JSONUtil.toJsonStr(param));
log.info("微信第三方平台接口:获取/刷新接口调用令牌,返回结果:{}", post);
JSONObject jsonObject = JSONUtil.parseObj(post);
return new ResultDto(CodeEnum.SUCCESS, jsonObject);
}
/**
* https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/2.0/api/ThirdParty/token/api_get_authorizer_info.html
* @param req
* @return
*/
public ResultDto getAuthorizerInfo(GetAuthorizerInfoReq req) {
String componentAccessToken = getComponentAccessToken();
Map<String, Object> param = new HashMap<>();
param.put("component_appid", ComponentAppid);
param.put("authorizer_appid", req.getAuthorizerAppid());
String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=" + componentAccessToken, JSONUtil.toJsonStr(param));
log.info("微信第三方平台接口:获取授权帐号信息,返回结果:{}", post);
JSONObject jsonObject = JSONUtil.parseObj(post);
return new ResultDto(CodeEnum.SUCCESS, jsonObject);
}
public ResultDto commitCode(CommitCodeReq req) {
Map<String, Object> param = new HashMap<>();
param.put("template_id", req.getTemplateId());
param.put("ext_json", req.getExtJson());
param.put("user_version", req.getUserVersion());
param.put("user_desc", req.getUserDesc());
String post = HttpUtil.post("https://api.weixin.qq.com/wxa/commit?access_token=" + req.getAccessToken(), JSONUtil.toJsonStr(param));
log.info("微信第三方平台接口:上传代码,返回结果:{}", post);
byte[] bytes = HttpUtil.downloadBytes("https://api.weixin.qq.com/wxa/get_qrcode?access_token=" + req.getAccessToken());
// String get = HttpUtil.get("https://api.weixin.qq.com/wxa/get_qrcode?access_token=" + req.getAccessToken());
// log.info("微信第三方平台接口:获取体验版二维码,返回结果:{}", get);
// JSONObject jsonObject = JSONUtil.parseObj(get);
return new ResultDto(CodeEnum.SUCCESS, bytes);
}
public ResultDto getQrcode(GetQrcodeReq req) {
String get = HttpUtil.get("https://api.weixin.qq.com/wxa/get_qrcode?access_token=" + req.getAccessToken());
log.info("微信第三方平台接口:获取体验版二维码,返回结果:{}", get);
// JSONObject jsonObject = JSONUtil.parseObj(get);
return new ResultDto(CodeEnum.SUCCESS, get);
}
相关参考:
微信开放平台_第三方平台授权流程_验证票据_小张写bug的博客-CSDN博客
微信开放平台---授权事件接收URL---Java_u011645644的博客-CSDN博客_授权事件接收url
java三方开放平台_微信开放平台---授权事件接收URL---Java_weixin_39978749的博客-CSDN博客
java三方开放平台_微信开放平台---授权事件接收URL---Java_weixin_39978749的博客-CSDN博客