微信第三方登陆
/** * 在公众号第三方平台创建审核通过后,微信服务器会向其“授权事件接收URL”每隔10分钟定时推送component_verify_ticket。第三方平台方在收到ticket推送后也需进行解密(详细请见【消息加解密接入指引】),接收到后必须直接返回字符串success。 * @param msg_signature * @param timestamp * @param nonce * @throws Exception */ @RequestMapping("/authorizer.do") public void authorizer(String msg_signature,String timestamp,String nonce) throws Exception{ String bodyXml = Dom4jUtils.recieveData(request); //String appid = Dom4jUtils.readStringXml(bodyXml, "AppId"); WeixinAuthorizer weixinAuthorizer=weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1); WXBizMsgCrypt wx=new WXBizMsgCrypt(weixinAuthorizer.getComponent_token(),weixinAuthorizer.getComponent_key(),weixinAuthorizer.getComponent_appid()); String result2 = wx.decryptMsg_AppId(msg_signature, timestamp, nonce, bodyXml); String infoType = Dom4jUtils.readStringXml(result2, "InfoType"); if(null!=infoType&&"component_verify_ticket".equals(infoType)){ String componentVerifyTicket = Dom4jUtils.readStringXml(result2, "ComponentVerifyTicket"); weixinAuthorizer.setComponentVerifyTicket(componentVerifyTicket); weixinAuthorizerService.save(weixinAuthorizer); logger.warn("componentVerifyTicket==="+componentVerifyTicket); }else if("unauthorized".equals(infoType)){//推送取消授权通知 String authorizerAppid = Dom4jUtils.readStringXml(result2, "AuthorizerAppid"); WeChatConfig weChatConfig = weChatConfigService.getWeChatConfigbyAppid(authorizerAppid); if(weChatConfig!=null){ weChatConfig.setUseState(1); weChatConfigService.save(weChatConfig); } } PrintWriter sl = response.getWriter(); sl.write("success"); sl.flush(); sl.close(); } /** * 获取授权码 * @param auth_code * @return * @throws Exception */ @RequestMapping("/getAuth_code.do") public String getAuth_code(String auth_code,String id) throws Exception{ User user=getLoginUser(); Provide provide=provideService.getObjectById(Provide.class, user.getAgentOrProvide()); logger.info("获取授权码成功"); WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1); weixinAuthorizer.setAuth_code(auth_code); weixinAuthorizerService.save(weixinAuthorizer); Map<String,String> mp = new HashMap<String,String>(); mp.put("component_appid", weixinAuthorizer.getComponent_appid()); mp.put("authorization_code", auth_code); JSONObject obj = JSONObject.fromObject(mp); logger.warn(obj.toString()); logger.warn("-------------------使用授权码换取公众号的授权信息---requestUrl------------------------"); JSONObject result=HttpTool.httpRequest("https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token="+weixinAuthorizer.getComponent_access_token(),"POST", obj.toString()); logger.warn(result.toString()); WeChatConfig weChatConfig=new WeChatConfig(); weChatConfig.setAppid(result.getJSONObject("authorization_info").get("authorizer_appid").toString()); if (result.has("errcode")) { logger.error("获取第三方平台access_token!errcode=" + result.getString("errcode") + ",errmsg = " + result.getString("errmsg")); } ApiGetAuthorizer apiGetAuthorizer=new ApiGetAuthorizer(); apiGetAuthorizer.setComponent_appid(weixinAuthorizer.getComponent_appid()); WeChatConfig oldweChatConfig=weChatConfigService.getWeChatConfigbyAppid(weChatConfig.getAppid()); if(null!=oldweChatConfig){ weChatConfig=oldweChatConfig; } weChatConfig.setAuthorizerType(1); weChatConfig.setAccess_token(result.getJSONObject("authorization_info").get("authorizer_access_token").toString()); weChatConfig.setAuthorizer_refresh_token(result.getJSONObject("authorization_info").get("authorizer_refresh_token").toString()); apiGetAuthorizer.setAuthorizer_appid(weChatConfig.getAppid()); JSONObject param = JSONObject.fromObject(apiGetAuthorizer ); JSONObject result1 = HttpTool.httpRequest("https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token="+weixinAuthorizer.getComponent_access_token(),"POST", param.toString()); ApiGetAuthorizerRet apiGetAuthorizerRet = (ApiGetAuthorizerRet)JSONObject.toBean(result1, ApiGetAuthorizerRet.class); weChatConfig.setName(apiGetAuthorizerRet.getAuthorizer_info().getNick_name()); weChatConfig.setHead_img(apiGetAuthorizerRet.getAuthorizer_info().getHead_img()); if(apiGetAuthorizerRet.getAuthorizer_info().getService_type_info().getId()==2){ weChatConfig.setTypes(0); }else{ weChatConfig.setTypes(1); } weChatConfig.setUseState(0);//启用 weChatConfig.setToUserName(apiGetAuthorizerRet.getAuthorizer_info().getUser_name()); weChatConfig.setProvide(provide); weChatConfigService.save(weChatConfig); List<WeChatMenu> rootList=weChatMenuService.getChatMenusByProvide(weChatConfig.getProvide()); WeChatConfigQuery weChatConfigQuery=new WeChatConfigQuery(); weChatConfigQuery.setMainNum(1); weChatConfigQuery.setProvide(weChatConfig.getProvide()); WeChatConfig manweChatConfig=weChatConfigService.getByProvideId(weChatConfigQuery);//查询是否有主服务号 if(null!=manweChatConfig){//发布菜单 String jsonStr=menu(manweChatConfig, rootList,weChatConfig);//从微信号 String restlut=HttpRequestTool.sendPost("https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+ weChatConfig.getAccess_token(),jsonStr); logger.warn("restlut="+restlut); }else{ String jsonStr=menu(weChatConfig, rootList,weChatConfig);//主微信号 String restlut=HttpRequestTool.sendPost("https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+ weChatConfig.getAccess_token(),jsonStr); logger.warn("restlut="+restlut); } if(null!=id){ return "redirect:../provide/list.do"; } return "redirect:../weChatConfig/list.do"; } /** * 公众号消息与事件接收 * * @param request * @param response * @throws Exception * @throws DocumentException * @throws IOException */ @RequestMapping(value = "/{appid}/callback.do") public void acceptMessageAndEvent(String msg_signature,String timestamp,String nonce,@PathVariable("appid") String appid) throws Exception { WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1); WXBizMsgCrypt wx=new WXBizMsgCrypt(weixinAuthorizer.getComponent_token(),weixinAuthorizer.getComponent_key(),weixinAuthorizer.getComponent_appid()); String bodyXml = Dom4jUtils.recieveData(request); String result2 = wx.decryptMsg(msg_signature, timestamp, nonce, bodyXml); String toUserName = Dom4jUtils.readStringXml(result2, "ToUserName"); String fromUserName = Dom4jUtils.readStringXml(result2, "FromUserName"); String msgType = Dom4jUtils.readStringXml(result2, "MsgType"); String event = Dom4jUtils.readStringXml(result2, "Event"); String content = Dom4jUtils.readStringXml(result2, "Content"); if (StringUtils.equalsIgnoreCase(toUserName, "gh_3c884a361561")) { logger.info("全网发布接入检测消息反馈开始----------------appid="+appid+"--------toUserName="+toUserName); checkWeixinAllNetworkCheck(request,response,bodyXml); return ; } WeChatUser weChatUser= new WeChatUser(); WeChatConfig weChatConfig=weChatConfigService.getWeChatConfigbyAppid(appid); //自动回复 WeChatInputReplyQuery weChatInputReplyQuery = new WeChatInputReplyQuery(); weChatInputReplyQuery.setConfigId(weChatConfig.getId()); pageInfo = weChatInputReplyService.findAll(weChatInputReplyQuery, null); //把自动回复拼上去 StringBuilder sb = new StringBuilder(); StringBuilder sb1 = new StringBuilder(); sb.append(weChatConfig.getAutoReply()); if(null!=pageInfo && null!= pageInfo && pageInfo.getList().size()>0){ //如果有可输入的内容. List<WeChatInputReply> list = pageInfo.getList(); for (WeChatInputReply weChatInputReply : list) { sb1.append("\n"+weChatInputReply.getInputValue()); sb1.append("、"+weChatInputReply.getInputValueName()); } } // content=WeChartTemp.CreateRelayCustomMsg(toUserName,fromUserName); // System.out.println("################"+fromUserName); // System.out.println("################"+toUserName); // String sEncryptMsg1 = wx.encryptMsg(content, timestamp, nonce); // PrintWriter writer = response.getWriter(); // writer.write(sEncryptMsg1); // writer.close(); if("subscribe".equals(event)) {//关注事件 String userInfor=HttpRequestTool.sendGet("https://api.weixin.qq.com/cgi-bin/user/info", "access_token="+weChatConfig.getAccess_token()+"&openid="+fromUserName+"&lang=zh_CN"); Gson gs=new Gson(); WeChatUser newweChatUser = gs.fromJson(userInfor, WeChatUser.class); synchronized (this) { if(weChatConfig.getMainNum()==1){//用户信息 只保存主微信用户信息 weChatUser=weChatUserService.getWeChatUserByOpenid(fromUserName); if(weChatUser==null){ newweChatUser.setSubscribeTime(new Date()); newweChatUser.setGuanzhu(1); newweChatUser.setOpenid(fromUserName); newweChatUser.setProvide(weChatConfig.getProvide()); newweChatUser.setToUserName(weChatConfig.getToUserName()); weChatUserService.save(newweChatUser); }else{ weChatUser.setCity(newweChatUser.getCity()); weChatUser.setCountry(newweChatUser.getProvince()); weChatUser.setCountry(newweChatUser.getCountry()); weChatUser.setNickname(newweChatUser.getNickname()); weChatUser.setSex(newweChatUser.getSex()); weChatUserService.save(weChatUser); } } } //查出这个配置下的自动回复 logger.warn(sb.append(sb1).toString());//顺序倒了.. content=WeChartTemp.responseCommonText(fromUserName,toUserName,event+"from_callback"); String sEncryptMsg = wx.encryptMsg(content, timestamp, nonce); response.getWriter().write(sEncryptMsg); }else if ("unsubscribe".equalsIgnoreCase(event)) {//取消关注 weChatUser=weChatUserService.getWeChatUserByOpenid(fromUserName); weChatUser.setGuanzhu(2); weChatUserService.save(weChatUser); }else if("text".equalsIgnoreCase(msgType)){ content ="输入有误,请按要求输入!"+sb1.toString(); content=WeChartTemp.responseCommonText(fromUserName,toUserName,content); //客户输入的信息 String recontent=Dom4jUtils.readStringXml(bodyXml, "Content"); if(null!=pageInfo && null!= pageInfo && pageInfo.getList().size()>0){ //如果有可输入的内容. List<WeChatInputReply> list = pageInfo.getList(); for (WeChatInputReply weChatInputReply : list) { if(weChatInputReply.getInputValue().equals(recontent) || weChatInputReply.getInputValueName().equals(recontent)){ if(weChatInputReply.getTypes()==0){ content = weChatInputReply.getReplyValue(); content=WeChartTemp.responseCommonText(fromUserName,toUserName,content); } if(weChatInputReply.getTypes()==1){ content=weChartArticleService.findArticleOne(weChatInputReply.getConfig().getProvide(),fromUserName,toUserName,8); if(content==null){ content="暂无数据,等待更新"; content=WeChartTemp.responseCommonText(fromUserName,toUserName,content); } } } } } String sEncryptMsg = wx.encryptMsg(content, timestamp, nonce); response.getWriter().write(sEncryptMsg); } } public void checkWeixinAllNetworkCheck(HttpServletRequest request, HttpServletResponse response,String xml) throws Exception{ String nonce = request.getParameter("nonce"); String timestamp = request.getParameter("timestamp"); String msgSignature = request.getParameter("msg_signature"); WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1); WXBizMsgCrypt pc=new WXBizMsgCrypt(weixinAuthorizer.getComponent_token(),weixinAuthorizer.getComponent_key(),weixinAuthorizer.getComponent_appid()); 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 Exception { String content = event + "from_callback"; logger.info("---全网发布接入检测------step.4-------事件回复消息 content="+content + " toUserName="+toUserName+" fromUserName="+fromUserName); replyTextMessage(request,response,content,toUserName,fromUserName); } public void processTextMessage(HttpServletRequest request, HttpServletResponse response,String content,String toUserName, String fromUserName) throws Exception{ 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再回复一次消息 try { replyApiTextMessage(request,response,content.split(":")[1],fromUserName); } catch (Exception e) { e.printStackTrace(); } } } public void replyApiTextMessage(HttpServletRequest request, HttpServletResponse response, String auth_code, String fromUserName) throws Exception { String authorization_code = auth_code; // 得到微信授权成功的消息后,应该立刻进行处理!!相关信息只会在首次授权的时候推送过来 logger.warn("------step.1----使用客服消息接口回复粉丝----逻辑开始-------------------------"); try { WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1); ApiComponentToken apiComponentToken = new ApiComponentToken(); apiComponentToken.setComponent_appid(weixinAuthorizer.getComponent_appid()); apiComponentToken.setComponent_appsecret(weixinAuthorizer.getComponent_appSecret()); apiComponentToken.setComponent_verify_ticket(weixinAuthorizer.getComponentVerifyTicket()); JSONObject param = JSONObject.fromObject(apiComponentToken); JSONObject api_component_token=HttpTool.sendPostUrl("https://api.weixin.qq.com/cgi-bin/component/api_component_token",param.toString(), "UTF-8"); logger.warn("api_component_token="+api_component_token.toString()); String component_access_token =JSONObject.fromObject(api_component_token).getString("component_access_token"); logger.warn("------step.2----使用客服消息接口回复粉丝------- component_access_token = "+component_access_token + "---------authorization_code = "+authorization_code); net.sf.json.JSONObject authorizationInfoJson =getApiQueryAuthInfo(weixinAuthorizer.getComponent_appid(), authorization_code, component_access_token); logger.warn("------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); sendMessage(obj, authorizer_access_token); } catch (Exception e) { e.printStackTrace(); } } /** * 发送客服消息 * @param obj * @param ACCESS_TOKEN * @return */ void sendMessage(Map<String,Object> obj,String ACCESS_TOKEN){ JSONObject json = JSONObject.fromObject(obj); logger.warn("--------发送客服消息---------json-----"+json.toString()); // 调用接口获取access_token JSONObject jsonObject = HttpTool.httpRequest("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+ACCESS_TOKEN, "POST", json.toString()); logger.warn("--------发送客服消息结果--"+jsonObject.toString()); } public JSONObject getApiQueryAuthInfo(String component_appid,String authorization_code,String component_access_token) throws Exception{ Map<String,String> mp = new HashMap<String,String>(); mp.put("component_appid", component_appid); mp.put("authorization_code", authorization_code); JSONObject obj = JSONObject.fromObject(mp); logger.warn(obj.toString()); logger.warn("-------------------3、使用授权码换取公众号的授权信息---requestUrl------------------------"); JSONObject result=HttpTool.httpRequest("https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token="+component_access_token,"POST", obj.toString()); logger.warn(result.toString()); if (result.has("errcode")) { logger.error("获取第三方平台access_token!errcode=" + result.getString("errcode") + ",errmsg = " + result.getString("errmsg")); } return result; } /** * 回复微信服务器"文本消息" * @param request * @param response * @param content * @param toUserName * @param fromUserName * @throws Exception */ public void replyTextMessage(HttpServletRequest request, HttpServletResponse response, String content, String toUserName, String fromUserName) throws Exception { 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 { WeixinAuthorizer weixinAuthorizer= weixinAuthorizerService.getObjectById(WeixinAuthorizer.class, 1); WXBizMsgCrypt pc=new WXBizMsgCrypt(weixinAuthorizer.getComponent_token(),weixinAuthorizer.getComponent_key(),weixinAuthorizer.getComponent_appid()); returnvaleue = pc.encryptMsg(replyMsg, createTime.toString(), "easemob"); logger.warn("------------------加密后的返回内容 returnvaleue: "+returnvaleue); } catch (AesException e) { e.printStackTrace(); } output(response, returnvaleue); } /** * 工具类:回复微信服务器"文本消息" * @param response * @param returnvaleue */ public void output(HttpServletResponse response,String returnvaleue){ try { PrintWriter pw = response.getWriter(); pw.write(returnvaleue); pw.flush(); } catch (IOException e) { e.printStackTrace(); } }