2. 验证服务器地址的有效性
一 验证消息的确来自微信服务器
1. 开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:
| 参数 | 描述 |
|---|---|
| signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
| timestamp | 时间戳 |
| nonce | 随机数 |
| echostr | 随机字符串 |
开发者通过检验signature对请求进行校验,加密/校验流程如下:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,
4) 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
二 代码
2.1 编写sha1方法,完整java代码如下:
/**
* 验签
* @param token 自定义的token
* @param timestamp 时间戳
* @param nonce 随机数
* @param signature 微信加密签名
* @return
*/
public static boolean getSha(String token,String timestamp,String nonce,String signature) {
try {
// (1)将token、timestamp、nonce三个参数进行字典序排序
String[] array = new String[] { token, timestamp, nonce};
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < 3; i++) {
sb.append(array[i]);
}
String str = sb.toString();
//(2)将三个参数字符串拼接成一个字符串进行sha1加密
//获取一个加密对象
MessageDigest md = MessageDigest.getInstance("SHA-1");
//加密
md.update(str.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);
}
log.info("微信加密签名signature====>"+signature);
log.info("用SHA算法生成安全签名后的数据:=====>>"+hexstr.toString());
if(signature.equals(hexstr.toString())) {
log.info("接入成功");
return true;
}else{
log.info("微信加密签名与SHA算法生成安全签名比对失败!");
return false;
}
} catch (NoSuchAlgorithmException e) {
log.info("微信加密签名与SHA算法生成安全签名比对过程中异常!");
return false;
}
}
2.2 完整接口代码如下
package com.grand.weichat.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.grand.weichat.util.utils;
import lombok.extern.log4j.Log4j;
@Controller
@Log4j
public class WxServlet {
@Value("${conf.token}")
private String token;
@RequestMapping("/wx")
public void wxHandle(HttpServletRequest request, HttpServletResponse response) {
try {
/* signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串*/
String signature=request.getParameter("signature");
String timestamp=request.getParameter("timestamp");
String nonce=request.getParameter("nonce");
String echostr=request.getParameter("echostr");
/**
* 1)将token、timestamp、nonce三个参数进行字典序排序
* 2)将三个参数字符串拼接成一个字符串进行sha1加密
* 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
* 4)若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
*/
boolean result=utils.getSha(token,timestamp, nonce,signature);
if(result) {
log.info("接入成功");
PrintWriter out = response.getWriter();
out.print(echostr);
out.flush();
out.close();
return;
}else{
log.info("接入失败");
return;
}
} catch (IOException e) {
log.info("接入失败");
return;
}
}
}
作者:皓月无边*半步青莲
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号