SpringMVC微信公众号服务器验证不通过

最近开始搞搞开放平台,先是TaoBaoSDK,挺好用的基本每碰到什么问题,就是各种没权限。。。

后来搞微信的,第一步卡了我一天。。。年纪大了,反应迟钝啊。。。

首先按照公众号平台里把信息配置好,这里我就不截图了

服务端刚开始调用的是Demo里WXBizMsgCrypt.verifyUrl(msgSignature,timeStamp,nonce,echoStr)

不要问我为什么,因为懒。。。

就是验不通过,经过核对参数、设置编码等等最后发现这个方法不是用来响应服务端验证的,而且Demo里似乎也没有现成的方法。。。。

于是动手开始改了(同学们要相信自己啊):

签名方法:考虑到Demo里那个方法是四个参数的,所以写了一个兼容多个参数的

1/** 2 * 签名数据 3 * @param args 签名数据列表 arg[0]必须为appId 4 * @return 签名结果 5 */ 6public String sign(String... args){ 7 /*** 不用看 begin,就是把第一个参数由appId换成token,因为我这个多账号,否则写死 ****/ 8 String appId = args[0]; 9 AppConf conf = getAppConf(appId); 10 args[0]=conf.getToken(); 11 /*** 不用看 end *****/ 12 13 // 字典序排序,如果有null的这里会报错 14 Arrays.sort(args); 15 // 字符串拼接 16 StringBuffer buffer = new StringBuffer(); 17 for(String str:args){ 18 if(str!=null){ 19 buffer.append(str); 20 } 21 } 22 try{ 23 // SHA1签名生成 24 MessageDigest md = MessageDigest.getInstance("SHA-1"); 25 md.update(buffer.toString().getBytes()); 26 byte[] digest = md.digest(); 27 28 StringBuffer hexstr = new StringBuffer(); 29 String shaHex = ""; 30 for (int i = 0; i < digest.length; i++) { 31 shaHex = Integer.toHexString(digest[i] & 0xFF); 32 if (shaHex.length() < 2) { 33 hexstr.append(0); 34 } 35 hexstr.append(shaHex); 36 } 37 return hexstr.toString(); 38 }catch(Exception ex){ 39 throw new BaseRuntimeException(WXServerError.sign(appId,args)); 40 } 41 42}

调用的地方

   - 签名返回报文,4个参数(不知道是不是这个,反正签了):

String sign =wxMsgCryptService.sign(info.getAppId(),timestamp,nonce,encrypt);

   - 响应服务端验证,3个参数(这个是正主)

1if(signature!=null){ 2 String sign = wxMsgCryptService.sign(appId,timestamp,nonce); 3 4 if(sign.equals(signature)){ 5 if(body==null){ 6 return echostr; 7 } 8 }else{ 9 throw new BaseRuntimeException(WXServerError.verify(appId,timestamp,nonce,signature)); 10 } 11}

返回部分:返回是我很费解的地方,可以是字符串、可以是xml、没有异常报文不是200的一律失败,不过好像也没什么不对。

1// 返回的直接是Http Body了 2@ResponseBody 3/** 我习惯了用扩展名来区分响应,微信那边配的是server/{appId}.xml 4 * 这样返回的就是xml了,那天支持json了换json吧 5 */ 6@RequestMapping("server/{appId}.*") 7public Object service( 8 @PathVariable("appId") String appId, 9 @RequestParam(value="signature",required=false)String signature, 10 @RequestParam(value="timestamp",required=false)String timestamp, 11 @RequestParam(value="nonce",required=false)String nonce, 12 @RequestParam(value="echostr",required=false)String echostr, 13 @RequestBody(required=false) String body){ 14 15 logger.info("accept -> signature:{},timestamp:{},nonce:{},echostr:{}",new Object[]{ 16 signature,timestamp,nonce,echostr 17 }); 18 // 配置的时候有三个选项:明文的时候就不验签了,估计不会有人这么配置吧 19 // 接受明文消息时,不进行验签 20 if(signature!=null){ 21 String sign = wxMsgCryptService.sign(appId,timestamp,nonce); 22 23 if(sign.equals(signature)){ 24 if(body==null){ 25 // 响应验证到这里就结束了,返回echostr,微信那边就验证通过了 26 return echostr; 27 } 28 }else{ 29 throw new BaseRuntimeException(WXServerError.verify(appId,timestamp,nonce,signature)); 30 } 31 } 32 33 logger.info("receive->{}",body); 34 35 36 // 以下接受到消息的处理,属于增值包 😜 37 38 MsgCryptInfo info = new MsgCryptInfo(); 39 info.setAppId(appId); 40 info.setNonce(nonce); 41 info.setSignature(signature); 42 info.setTimeStamp(timestamp); 43 // 里面判断要不要解密消息,不要直接返回了 44 WXMessage message = wxMessageService.getMessage(info,body); 45 // 去找对应的消息处理器生成返回消息 46 message = wxMessageService.reply(message); 47 // 无返回消息时 48 if(message==null){ 49 // 官方说返回"success"字串也是成功,我是不会让它走到这个分支的,邪恶啊 50 return DEFAULT_REPLY; 51 } 52 // 接受明文消息时,不进行验签 53 if(signature!=null){ 54 // 消息加密部分,官方的Demo抄下来就好了 55 message = wxMessageService.encryptMessage(info, message); 56 } 57 58 return message; 59}

PS:当时我用verifyURL跑不过验证的时候,我内心时崩溃的,在想难道未认证的订阅号连这个都不让干了。所以我终究还是低估了微信对于个人开发者的友好

点赞
收藏

评论区

加载中...

相关推荐

微标题信公众号文章,阅读数,点赞数历史文章抓取

微标题信公众号文章,阅读数,点赞数历史文章抓取需求最近在做舆情与微信文章相关的数据抓取,发现微信公众号有些难点很难克服。市面上流行的数据抓取思路要么被腾讯封杀,要么操作难度大。解决方案搜狗微信无法采集历史,而且搜索也不按时间排序。获取的数据的价值不高,仅仅可以通过他获取公众号的biz。微信公众平台微信公

手写一个仿微信登录的nodejs程序

前言首先,我们看一下微信开放文档中的一张图:上面的一幅图中清楚地介绍了微信登录整个过程,下面对图上所示进行总结:一、二维码的获得1.用户打开登录网页后,登录网页后台根据微信OAuth2.0协议向微信开发平台请求授权登录,并传递事先在微信开发平台中审核通过的AppID和AppSecrect等参数;2.微信开发平台对AppID等参数进行验证,并向

Android深入四大组件(一)应用程序启动过程(后篇)

Android框架层Android深入四大组件categories:Android框架层本文首发于微信公众号「刘望舒」1.ActivityManageService到ApplicationThread的调用流程AMS的startActivity方法中return了startActivityAsUser方法:<!moreframeworks/base/s

1小时搭建微信小程序后端

CoNami小程序Demo端到端开发指南1\.注册登录微信公众平台登录https://mp.weixin.qq.com,里面有详细的指引,这里就不赘述了。这里注册最后得到的比较重要的东西包括两个(https://www.oschina.net/action/GoToLink

2020微信运动一键刷步数,让你重回排行榜第一

微信运动很久之前就有了,不过我是最近才开始玩的,你的微信运动排行榜里是不总有人长期霸占第一,他应该不是每天都在运动,很可能是使用了工具刷的,今天就分享下。在线刷微信运动步数首先在应用商店下载一个乐心健康app ,使用手机号注册,并且设置一个登陆密码,然后在数据共享里开启第三方同步(包含微信运动,支付宝运动,阿里体育,需要关注他们的公

JAVA获取微信小程序openid和获取公众号openid,以及通过openid获取用户信息

一,首先说明下这个微信的openid  为了识别用户,每个用户针对每个公众号会产生一个安全的OpenID,如果需要在多公众号、移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下,绑定后,一个用户虽然对多个公众号和应用有多个不同的OpenID,但他对所有这些同一开放平台账号下的公众