文档章节

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

 海岸Thirty
发布于 2017/04/09 16:32
字数 939
阅读 72
收藏 0
点赞 0
评论 0

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

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

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

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

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

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

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

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

/**
 * 签名数据
 * @param args 签名数据列表 arg[0]必须为appId
 * @return 签名结果
 */
public String sign(String... args){
    /*** 不用看 begin,就是把第一个参数由appId换成token,因为我这个多账号,否则写死 ****/
	String appId = args[0];
	AppConf conf = getAppConf(appId);
	args[0]=conf.getToken();
    /*** 不用看 end  *****/

	// 字典序排序,如果有null的这里会报错
	Arrays.sort(args);
	// 字符串拼接
	StringBuffer buffer = new StringBuffer();
	for(String str:args){
		if(str!=null){
			buffer.append(str);
		}
	}
	try{
		// SHA1签名生成
		MessageDigest md = MessageDigest.getInstance("SHA-1");
		md.update(buffer.toString().getBytes());
		byte[] digest = md.digest();

		StringBuffer hexstr = new StringBuffer();
		String shaHex = "";
		for (int i = 0; i < digest.length; i++) {
			shaHex = Integer.toHexString(digest[i] & 0xFF);
			if (shaHex.length() < 2) {
				hexstr.append(0);
			}
			hexstr.append(shaHex);
		}
		return hexstr.toString();
	}catch(Exception ex){
		throw new BaseRuntimeException(WXServerError.sign(appId,args));
	}
	
}

调用的地方

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

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

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

if(signature!=null){
	String sign = wxMsgCryptService.sign(appId,timestamp,nonce);
	
	if(sign.equals(signature)){
		if(body==null){
			return echostr;
		}
	}else{
		throw new BaseRuntimeException(WXServerError.verify(appId,timestamp,nonce,signature));
	}
}

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

// 返回的直接是Http Body了
@ResponseBody
/** 我习惯了用扩展名来区分响应,微信那边配的是server/{appId}.xml
 *  这样返回的就是xml了,那天支持json了换json吧
 */
@RequestMapping("server/{appId}.*")
public Object service(
	@PathVariable("appId") String appId,
	@RequestParam(value="signature",required=false)String signature,
	@RequestParam(value="timestamp",required=false)String timestamp,
	@RequestParam(value="nonce",required=false)String nonce,
	@RequestParam(value="echostr",required=false)String echostr,
	@RequestBody(required=false) String body){

	logger.info("accept -> signature:{},timestamp:{},nonce:{},echostr:{}",new Object[]{
			signature,timestamp,nonce,echostr
	});
	// 配置的时候有三个选项:明文的时候就不验签了,估计不会有人这么配置吧
	// 接受明文消息时,不进行验签
	if(signature!=null){
		String sign = wxMsgCryptService.sign(appId,timestamp,nonce);
		
		if(sign.equals(signature)){
			if(body==null){
                // 响应验证到这里就结束了,返回echostr,微信那边就验证通过了
				return echostr;
			}
		}else{
			throw new BaseRuntimeException(WXServerError.verify(appId,timestamp,nonce,signature));
		}
	}
	
	logger.info("receive->{}",body);
	
     
    // 以下接受到消息的处理,属于增值包 😜
	
    MsgCryptInfo info = new MsgCryptInfo();
	info.setAppId(appId);
	info.setNonce(nonce);
	info.setSignature(signature);
	info.setTimeStamp(timestamp);
	// 里面判断要不要解密消息,不要直接返回了
	WXMessage message = wxMessageService.getMessage(info,body);
	// 去找对应的消息处理器生成返回消息
	message = wxMessageService.reply(message);
	// 无返回消息时
	if(message==null){
        // 官方说返回"success"字串也是成功,我是不会让它走到这个分支的,邪恶啊
		return DEFAULT_REPLY;
	}
	// 接受明文消息时,不进行验签
	if(signature!=null){
        // 消息加密部分,官方的Demo抄下来就好了
		message = wxMessageService.encryptMessage(info, message);
	}
	
	return message;
}

 

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

 

 

 

© 著作权归作者所有

共有 人打赏支持
粉丝 3
博文 11
码字总数 4670
作品 0
浦东
高级程序员
记一次外包项目微信接口开发流程-spring-boot

近期帮朋友做了几个用到微信公众号接口的活,所以总结下。 一、微信公众号后台配置 公众号分订阅号,服务号,企业号,可以调用的接口权限各不相同,这里就不赘述,参考官方说明。 登陆公众号...

北风刮的不认真了
2017/10/20
0
5
基于 SpringBoot 的微信公众号快速开发框架--FastBootWeixin

FastBootWeixin 是一款基于 SpringBoot、Spring、SpringMVC 的微信快速开发框架。使用简单快捷,可以快速的完成一个微信公众号。 在使用本框架前建议对微信公众号开发文档有所了解,不过在不...

光闪
2017/09/18
1K
2
Java 微信公众号 MVC 开发框架--jwx

jwx是开源的java公众号开发MVC框架,基于spring配置文件和微信消息或事件注解,通过微信上下文处理一个或多个微信公众号服务请求。 目的主要有两个,其一生封装微信请求xml消息为java实体对象...

落叶走天涯
2017/03/28
1K
0
光闪/FastBootWeixin

How To Use 本框架基于SpringBoot实现,使用注解完成快速开发,可以快速的完成一个微信公众号,重新定义公众号开发。 在使用本框架前建议对微信公众号开发文档有所了解,不过在不了解公众号文...

光闪
2017/09/18
0
0
微信token问题

微信公众号设置服务器配置的时候,我有一个问题,他应该是拿着token去外网可访问的服务器去验证token,那放在服务器上的项目应该是通过配置文件xml或者什么springmvc.xml去后台找对应的class...

被编程耽误的相声演员
01/15
0
0
Docker部署SpringBoot项目整合Redis镜像做访问计数Demo

大概就几个步骤 1.安装 Docker CE 2.运行 Redis 镜像 3.Java 环境准备 4.项目准备 5.编写 Dockerfile 6.发布项目 7.测试服务 环境准备 系统:Ubuntu 17.04 x64 Docker 17.12.0-ce IP:45.32.3...

小致dad
07/15
0
0
Spring编程式和声明式事务实例讲解

Java面试通关手册(Java学习指南):https://github.com/Snailclimb/JavaGuide 历史回顾: 可能是最漂亮的Spring事务管理详解 Spring事务管理 Spring支持两种方式的事务管理: 编程式事务管理...

snailclimb
05/23
0
0
微信公共平台开发者url/token 认证(springmvc3.2.4)

bae升级到3,所以转战到sae。在此,记录一下遇到的问题。 sae java环境, 1.jdk1.6,服务器jetty7.x 2.自己上传的项目里面的jar包不能跟sae上的冲突。 因为自己的项目是maven构建,用到了dom...

DemoDoc
2014/05/01
0
0
微信开发:接入微信入口

一,申请开发者账号,进行服务器配置 首先我们得先有一个公众号,到微信公众号平台申请一个,本人申请的是订阅号。网址:https://mp.weixin.qq.com 还需要一个外网地址接口微信推送的消息,微...

xiaofli007
2016/06/20
130
0
关于Java本地服务接入微信平台进行调试的实现

趋于越来越多的社交需求,使得微信公众平台开放了许多可接入、定制的个性化接口,例如:消息的收发管理、素材管理等等。 本文是基于你已有公众号或者微信公众测试号的情况下进行介绍的。 首先...

Laughing_Vzr
2016/02/02
347
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

高效编写Dockerfile的几条准则

概述 Dockerfile 是专门用来进行自动化构建镜像的编排文件(就像Jenkins 2.0时代的Jenkinsfile是对Jenkins的Job和Stage的编排一样),我们可以通过 docker build 命令来自动化地从 Dockerfi...

小致dad
45分钟前
0
0
SpringBoot | 第十章:Swagger2的集成和使用

前言 前一章节介绍了mybatisPlus的集成和简单使用,本章节开始接着上一章节的用户表,进行Swagger2的集成。现在都奉行前后端分离开发和微服务大行其道,分微服务及前后端分离后,前后端开发的...

oKong
今天
9
0
Python 最小二乘法 拟合 二次曲线

Python 二次拟合 随机生成数据,并且加上噪声干扰 构造需要拟合的函数形式,使用最小二乘法进行拟合 输出拟合后的参数 将拟合后的函数与原始数据绘图后进行对比 import numpy as npimport...

阿豪boy
今天
7
0
云拿 无人便利店

附近(上海市-航南路)开了家无人便利店.特意进去体验了一下.下面把自己看到的跟大家分享下. 经得现场工作人员同意后拍了几张照片.从外面看是这样.店门口的指导里强调:不要一次扫码多个人进入....

周翔
昨天
1
0
Java设计模式学习之工厂模式

在Java(或者叫做面向对象语言)的世界中,工厂模式被广泛应用于项目中,也许你并没有听说过,不过也许你已经在使用了。 简单来说,工厂模式的出现源于增加程序序的可扩展性,降低耦合度。之...

路小磊
昨天
197
1
npm profile 新功能介绍

转载地址 npm profile 新功能介绍 npm新版本新推来一个功能,npm profile,这个可以更改自己简介信息的命令,以后可以不用去登录网站来修改自己的简介了 具体的这个功能的支持大概是在6这个版...

durban
昨天
1
0
Serial2Ethernet Bi-redirection

Serial Tool Serial Tool is a utility for developing serial communications, custom protocols or device testing. You can set up bytes to send accordingly to your protocol and save......

zungyiu
昨天
1
0
python里求解物理学上的双弹簧质能系统

物理的模型如下: 在这个系统里有两个物体,它们的质量分别是m1和m2,被两个弹簧连接在一起,伸缩系统为k1和k2,左端固定。假定没有外力时,两个弹簧的长度为L1和L2。 由于两物体有重力,那么...

wangxuwei
昨天
0
0
apolloxlua 介绍

##项目介绍 apolloxlua 目前支持javascript到lua的翻译。可以在openresty和luajit里使用。这个工具分为两种模式, 一种是web模式,可以通过网页使用。另外一种是tool模式, 通常作为大规模翻...

钟元OSS
昨天
2
0
Mybatis入门

简介: 定义:Mybatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。 途径:MyBatis通过XML文件或者注解的形式配置映射,实现数据库查询。 特性:动态SQL语句。 文件结构:Mybat...

霍淇滨
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部