获取ticket

master
ck 5 years ago
parent 1a8c1d4a58
commit 34e5b63738

@ -18,6 +18,7 @@
<properties>
<java.version>1.8</java.version>
<weixin-java-open.version>3.8.0</weixin-java-open.version>
</properties>
<dependencies>
@ -216,8 +217,27 @@
<version>1.4.8</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-open</artifactId>
<version>${weixin-java-open.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
</dependencies>
<build>

@ -0,0 +1,124 @@
package com.bsd.say.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory;
/**
* @author <a href="https://github.com/007gzs">007</a>
*/
@ConfigurationProperties(prefix = "wechat.redis")
public class RedisProperies extends JedisPoolConfig {
private String host = "111.229.204.101";
private int port = 63790;
private String password = "1qaz2wsx";
private int database = 4;
private int connectionTimeout = Protocol.DEFAULT_TIMEOUT;
private int soTimeout = Protocol.DEFAULT_TIMEOUT;
private String clientName;
private boolean ssl;
private SSLSocketFactory sslSocketFactory;
private SSLParameters sslParameters;
private HostnameVerifier hostnameVerifier;
public boolean isSsl() {
return ssl;
}
public void setSsl(boolean ssl) {
this.ssl = ssl;
}
public SSLSocketFactory getSslSocketFactory() {
return sslSocketFactory;
}
public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
this.sslSocketFactory = sslSocketFactory;
}
public SSLParameters getSslParameters() {
return sslParameters;
}
public void setSslParameters(SSLParameters sslParameters) {
this.sslParameters = sslParameters;
}
public HostnameVerifier getHostnameVerifier() {
return hostnameVerifier;
}
public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
this.hostnameVerifier = hostnameVerifier;
}
public String getHost() {
return host;
}
public void setHost(String host) {
if (host == null || "".equals(host)) {
host = Protocol.DEFAULT_HOST;
}
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
if ("".equals(password)) {
password = null;
}
this.password = password;
}
public int getDatabase() {
return database;
}
public void setDatabase(int database) {
this.database = database;
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
if ("".equals(clientName)) {
clientName = null;
}
this.clientName = clientName;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public int getSoTimeout() {
return soTimeout;
}
public void setSoTimeout(int soTimeout) {
this.soTimeout = soTimeout;
}
}

@ -1,18 +1,28 @@
package com.bsd.say.controller;
import com.bsd.say.config.RedisProperies;
import com.bsd.say.service.WxOpenServiceDemo;
import com.bsd.say.service.impl.WeixinService;
import com.bsd.say.util.LogUtils;
import com.bsd.say.util.MessageUtil;
import com.bsd.say.util.Xml2MapUtil;
import com.bsd.say.util.wechat.AesException;
import com.bsd.say.util.wechat.WXBizMsgCrypt;
import com.sun.org.apache.bcel.internal.generic.NEW;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -39,94 +49,43 @@ public class WechatController {
private String componentAppId;
@Resource
private RedisTemplate redisTemplate;
@Autowired
private WxOpenServiceDemo wxOpenService;
Logger logger = LogUtils.getBussinessLogger();
@Autowired
private WeixinService weixinService;
/**
* component_verify_ticket authorized
*/
@PostMapping(value = "/getComponentVerifyTicket")
@ResponseBody
public void getComponentVerifyTicket(HttpServletRequest request, HttpServletResponse response) throws Exception {
String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp");
String signature = request.getParameter("signature");
String msgSignature = request.getParameter("msg_signature");
// String postData = request.getParameter("postData");
logger.info("nonce: " + nonce);
logger.info("timestamp: " + timestamp);
logger.info("signature: " + signature);
logger.info("msgSignature: " + msgSignature);
// Map<String, String> map= MessageUtil.parseXml(request);
// System.out.println(map.toString());
StringBuilder sb = new StringBuilder();
BufferedReader in = request.getReader();
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
@RequestMapping("/getComponentVerifyTicket")
public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp,
@RequestParam("nonce") String nonce, @RequestParam("signature") String signature,
@RequestParam(name = "encrypt_type", required = false) String encType,
@RequestParam(name = "msg_signature", required = false) String msgSignature) {
this.logger.info(
"\n接收微信请求[signature=[{}], encType=[{}], msgSignature=[{}],"
+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
signature, encType, msgSignature, timestamp, nonce, requestBody);
if (!StringUtils.equalsIgnoreCase("aes", encType)
|| !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {
throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
}
String postData = sb.toString();
logger.info("postData: " + postData);
try {
//这个类是微信官网提供的解密类,需要用到消息校验Token 消息加密Key和服务平台appid
WXBizMsgCrypt pc = new WXBizMsgCrypt(componentToken,
aesKey, componentAppId);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
dbf.setXIncludeAware(false);
dbf.setExpandEntityReferences(false);
DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(postData);
InputSource is = new InputSource(sr);
org.w3c.dom.Document document = db.parse(is);
org.w3c.dom.Element root = document.getDocumentElement();
NodeList nodelist1 = root.getElementsByTagName("Encrypt");
String encrypt = nodelist1.item(0).getTextContent();
String format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>";
String fromXML = String.format(format, encrypt);
String xml = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML);
Map<String, Object> result = Xml2MapUtil.xml2map(xml);// 将xml转为map
String componentVerifyTicket = MapUtils.getString(result, "ComponentVerifyTicket");
// aes加密的消息
WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody,
wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
this.logger.debug("\n消息解密后内容为\n{} ", inMessage.toString());
try {
String out = wxOpenService.getWxOpenComponentService().route(inMessage);
this.logger.debug("\n组装回复信息{}", out);
} catch (WxErrorException e) {
this.logger.error("receive_ticket", e);
}
logger.info("----verify ticket--" + componentVerifyTicket);
// 存储平台授权票据,保存ticket
String TICKET = componentVerifyTicket;
redisTemplate.opsForValue().set("component_verify_ticket", TICKET);
} catch (Exception e) {
// log.error(e.getMessage(), e);
e.printStackTrace();
}
// WeChatUtils.responseReplyMessage(response, "success");
output(response, "success");
return "success";
}
/**
@ -146,43 +105,7 @@ public class WechatController {
}
}
// /**
// * 处理授权事件的推送
// *
// * @param request
// * @throws IOException
// * @throws AesException
// * @throws DocumentException
// */
// public void processAuthorizeEvent(HttpServletRequest request) throws IOException, DocumentException, AesException {
// String nonce = request.getParameter("nonce");
// String timestamp = request.getParameter("timestamp");
// String signature = request.getParameter("signature");
// String msgSignature = request.getParameter("msg_signature");
//
// if (!StringUtils.isNotBlank(msgSignature))
// return;// 微信推送给第三方开放平台的消息一定是加过密的,无消息加密无法解密消息
// boolean isValid = checkSignature(COMPONENT_TOKEN, signature, timestamp, nonce);
// if (isValid) {
// StringBuilder sb = new StringBuilder();
// BufferedReader in = request.getReader();
// String line;
// while ((line = in.readLine()) != null) {
// sb.append(line);
// }
// String xml = sb.toString();
//// LogUtil.info("第三方平台全网发布-----------------------原始 Xml="+xml);
// String encodingAesKey = COMPONENT_ENCODINGAESKEY;// 第三方平台组件加密密钥
// String appId = getAuthorizerAppidFromXml(xml);// 此时加密的xml数据中ToUserName是非加密的解析xml获取即可
// //LogUtil.info("第三方平台全网发布-------------appid----------getAuthorizerAppidFromXml(xml)-----------appId="+appId);
// WXBizMsgCrypt pc = new WXBizMsgCrypt(COMPONENT_TOKEN, encodingAesKey, COMPONENT_APPID);
// xml = pc.decryptMsg(msgSignature, timestamp, nonce, xml);
//// LogUtil.info("第三方平台全网发布-----------------------解密后 Xml="+xml);
// processAuthorizationEvent(xml);
// }
// }
//
//
@RequestMapping(value = "/{appid}/callback", method = {RequestMethod.GET, RequestMethod.POST})
public void callBackEvent(HttpServletRequest request, HttpServletResponse response) throws IOException, DocumentException, AesException {
@ -209,117 +132,28 @@ public class WechatController {
//// LogUtil.info("全网发布接入检测消息反馈开始---------------APPID="+ APPID +"------------------------toUserName="+toUserName);
// checkWeixinAllNetworkCheck(request,response,xml);
}
//
//
// public void checkWeixinAllNetworkCheck(HttpServletRequest request, HttpServletResponse response,String xml) throws DocumentException, IOException, AesException{
// String nonce = request.getParameter("nonce");
// String timestamp = request.getParameter("timestamp");
// String msgSignature = request.getParameter("msg_signature");
//
// WXBizMsgCrypt pc = new WXBizMsgCrypt(componentToken, aesKey, componentAppId);
// xml = pc.decryptMsg(msgSignature, timestamp, nonce, xml);
//
// Document doc = DocumentHelper.parseText(xml);
// Element rootElt = doc.getRootElement();
// String msgType = rootElt.elementText("MsgType");
// String toUserName = rootElt.elementText("ToUserName");
// String fromUserName = rootElt.elementText("FromUserName");
//
//// LogUtil.info("---全网发布接入检测--step.1-----------msgType="+msgType+"-----------------toUserName="+toUserName+"-----------------fromUserName="+fromUserName);
//// LogUtil.info("---全网发布接入检测--step.2-----------xml="+xml);
// if("event".equals(msgType)){
//// LogUtil.info("---全网发布接入检测--step.3-----------事件消息--------");
// String event = rootElt.elementText("Event");
// replyEventMessage(request,response,event,toUserName,fromUserName);
// }else if("text".equals(msgType)){
//// LogUtil.info("---全网发布接入检测--step.3-----------文本消息--------");
// String content = rootElt.elementText("Content");
// processTextMessage(request,response,content,toUserName,fromUserName);
// }
// }
//
// public void replyEventMessage(HttpServletRequest request, HttpServletResponse response, String event, String toUserName, String fromUserName) throws DocumentException, IOException {
// String content = event + "from_callback";
//// LogUtil.info("---全网发布接入检测------step.4-------事件回复消息 content="+content + " toUserName="+toUserName+" fromUserName="+fromUserName);
// replyTextMessage(request,response,content,toUserName,fromUserName);
// }
//
//
// /**
// * 回复微信服务器"文本消息"
// * @param request
// * @param response
// * @param content
// * @param toUserName
// * @param fromUserName
// * @throws DocumentException
// * @throws IOException
// */
// public void replyTextMessage(HttpServletRequest request, HttpServletResponse response, String content, String toUserName, String fromUserName) throws DocumentException, IOException {
// Long createTime = Calendar.getInstance().getTimeInMillis() / 1000;
// StringBuffer sb = new StringBuffer();
// sb.append("<xml>");
// sb.append("<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>");
// sb.append("<FromUserName><![CDATA["+toUserName+"]]></FromUserName>");
// sb.append("<CreateTime>"+createTime+"</CreateTime>");
// sb.append("<MsgType><![CDATA[text]]></MsgType>");
// sb.append("<Content><![CDATA["+content+"]]></Content>");
// sb.append("</xml>");
// String replyMsg = sb.toString();
//
// String returnvaleue = "";
// try {
// WXBizMsgCrypt pc = new WXBizMsgCrypt(componentToken, aesKey, componentAppId);
// returnvaleue = pc.encryptMsg(replyMsg, createTime.toString(), "easemob");
//// logger.info("------------------加密后的返回内容 returnvaleue "+returnvaleue);
// } catch (AesException e) {
// e.printStackTrace();
// }
// output(response, returnvaleue);
// }
//
// public void processTextMessage(HttpServletRequest request, HttpServletResponse response,String content,String toUserName, String fromUserName) throws IOException, DocumentException{
// if("TESTCOMPONENT_MSG_TYPE_TEXT".equals(content)){
// String returnContent = content+"_callback";
// replyTextMessage(request,response,returnContent,toUserName,fromUserName);
// }else if(StringUtils.startsWithIgnoreCase(content, "QUERY_AUTH_CODE")){
// output(response, "");
// //接下来客服API再回复一次消息
// replyApiTextMessage(request,response,content.split(":")[1],fromUserName);
// }
// }
//
// public void replyApiTextMessage(HttpServletRequest request, HttpServletResponse response, String auth_code, String fromUserName) throws DocumentException, IOException {
// String authorization_code = auth_code;
// // 得到微信授权成功的消息后,应该立刻进行处理!!相关信息只会在首次授权的时候推送过来
// logger.info("------step.1----使用客服消息接口回复粉丝----逻辑开始-------------------------");
// try {
// ApiComponentToken apiComponentToken = new ApiComponentToken();
// apiComponentToken.setComponent_appid(COMPONENT_APPID);
// apiComponentToken.setComponent_appsecret(COMPONENT_APPSECRET);
// WeixinOpenAccountEntity entity = getWeixinOpenAccount(APPID);
// apiComponentToken.setComponent_verify_ticket(entity.getTicket());
// String component_access_token = JwThirdAPI.getAccessToken(apiComponentToken);
//
// logger.info("------step.2----使用客服消息接口回复粉丝------- component_access_token = "+component_access_token + "---------authorization_code = "+authorization_code);
// net.sf.json.JSONObject authorizationInfoJson = JwThirdAPI.getApiQueryAuthInfo(COMPONENT_APPID, authorization_code, component_access_token);
// logger.info("------step.3----使用客服消息接口回复粉丝-------------- 获取authorizationInfoJson = "+authorizationInfoJson);
// net.sf.json.JSONObject infoJson = authorizationInfoJson.getJSONObject("authorization_info");
// String authorizer_access_token = infoJson.getString("authorizer_access_token");
//
//
// Map<String,Object> obj = new HashMap<String,Object>();
// Map<String,Object> msgMap = new HashMap<String,Object>();
// String msg = auth_code + "_from_api";
// msgMap.put("content", msg);
//
// obj.put("touser", fromUserName);
// obj.put("msgtype", "text");
// obj.put("text", msgMap);
// JwThirdAPI.sendMessage(obj, authorizer_access_token);
// } catch (WexinReqException e) {
// e.printStackTrace();
// }
//
// }
@RequestMapping("test")
public void test(){
JedisPool pool = new JedisPool();
RedisProperies redisProperies = new RedisProperies();
if (pool == null) {
synchronized (WxOpenServiceDemo.class) {
if (pool == null) {
pool = new JedisPool(redisProperies, redisProperies.getHost(),
redisProperies.getPort(), redisProperies.getConnectionTimeout(),
redisProperies.getSoTimeout(), redisProperies.getPassword(),
redisProperies.getDatabase(), redisProperies.getClientName(),
redisProperies.isSsl(), redisProperies.getSslSocketFactory(),
redisProperies.getSslParameters(), redisProperies.getHostnameVerifier());
}
}
}
Jedis jedis = null;
RedisProperies properies = new RedisProperies();
jedis = pool.getResource();
System.out.println(jedis.get("wechat_component_verify_ticket:wx474350bcaea2d745"));
}
}

@ -0,0 +1,69 @@
package com.bsd.say.service;
import com.bsd.say.config.RedisProperies;
import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage;
import me.chanjar.weixin.open.api.impl.WxOpenMessageRouter;
import me.chanjar.weixin.open.api.impl.WxOpenServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisPool;
import javax.annotation.PostConstruct;
/**
* @author <a href="https://github.com/007gzs">007</a>
*/
@Service
public class WxOpenServiceDemo extends WxOpenServiceImpl {
@Value("${wechat.aesKey}")
private String aesKey;
@Value("${wechat.componentToken}")
private String componentToken;
@Value("${wechat.appId}")
private String appId;
@Value("${wechat.componentAppId}")
private String componentAppId;
@Value("${wechat.componentAppSecret}")
private String componentAppSecret;
private Logger logger = LoggerFactory.getLogger(getClass());
private static JedisPool pool;
private WxOpenMessageRouter wxOpenMessageRouter;
@PostConstruct
public void init() {
WxOpenInRedisConfigStorage inRedisConfigStorage = new WxOpenInRedisConfigStorage(getJedisPool());
inRedisConfigStorage.setComponentAppId(componentAppId);
inRedisConfigStorage.setComponentAppSecret(componentAppSecret);
inRedisConfigStorage.setComponentToken(componentToken);
inRedisConfigStorage.setComponentAesKey(aesKey);
setWxOpenConfigStorage(inRedisConfigStorage);
wxOpenMessageRouter = new WxOpenMessageRouter(this);
wxOpenMessageRouter.rule().handler((wxMpXmlMessage, map, wxMpService, wxSessionManager) -> {
logger.info("\n接收到 {} 公众号请求消息,内容:{}", wxMpService.getWxMpConfigStorage().getAppId(), wxMpXmlMessage);
return null;
}).next();
}
public WxOpenMessageRouter getWxOpenMessageRouter(){
return wxOpenMessageRouter;
}
private JedisPool getJedisPool() {
RedisProperies redisProperies = new RedisProperies();
if (pool == null) {
synchronized (WxOpenServiceDemo.class) {
if (pool == null) {
pool = new JedisPool(redisProperies, redisProperies.getHost(),
redisProperies.getPort(), redisProperies.getConnectionTimeout(),
redisProperies.getSoTimeout(), redisProperies.getPassword(),
redisProperies.getDatabase(), redisProperies.getClientName(),
redisProperies.isSsl(), redisProperies.getSslSocketFactory(),
redisProperies.getSslParameters(), redisProperies.getHostnameVerifier());
}
}
}
return pool;
}
}
Loading…
Cancel
Save