一、申请一个微信公众号,具体申请流程就不一一诉说了。
二、进入公众号平台,在下方开发者中心中基本配置查看AppID(应用ID)、AppSecret(应用密钥)如图1所示:
三、设置你的服务器请求地址(注:服务器必须能外网访问),并设置token(令牌),令牌作用为验证链接的令牌,当设置链接的时候,微信服务器会发送一个GET请求到你设置的服务器链接上,你必须要在服务器上验证这个GET请求,并原样返回echostr参数内容则接入生效,成为开发者成功,否则接入失败。
加密/校验流程如下:
1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
验证请求方法(用的SpringMvc):
@RequestMapping(value="wechatInterface",method = RequestMethod.GET)
@ResponseBody
public String checktInterface(HttpServletRequest request,HttpServletResponse response){
log.info("进入校验微信连接方法");
String signature = request.getParameter("signature"); // 微信加密签名
String timestamp = request.getParameter("timestamp"); // 时间戳
String nonce = request.getParameter("nonce");// 随机数
String echostr = request.getParameter("echostr");// 随机字符串
log.info("获取的加密签名 :"+signature);
log.info("获取的时间戳 :"+timestamp);
log.info("获取的随机数 :"+nonce);
log.info("获取的随机字符串 :"+echostr);
log.info("--------------------------------");
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (WxVerify.verifyHttp(signature, timestamp, nonce)) {
log.info("校验成功反回随机码:"+echostr);
return echostr;
} else {
log.info("不是微信服务器发来的请求,请小心!");
return null;
}
}
验证签名方法:
package com.wx.common.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
* 微信链接校验
* 步骤:
* 1.将token、timestamp、nonce三个参数进行字典序排序
* 2.将三个参数字符串拼接成一个字符串进行sha1加密
* 3.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
* @author Hua
*
*/
public class WxVerify {
/**
* 微信请求验证
* @param signature 原始的加密签名字符串
* @param timestamp 时间戳信息
* @param nonce 随机数
* @return
*/
public static boolean verifyHttp(String signature,String timestamp,String nonce){
//1.将token、timestamp、nonce三个参数进行字典序排序
//先构造一个数组
String[] params = new String[]{Constants.TOKEN,timestamp,nonce};
//实现按字典属性排序
Arrays.sort(params);
//2.将三个参数字符串拼接成一个字符串
StringBuilder buidler = new StringBuilder();
//拼接字符串
for (int i = 0; i < params.length; i++) {
buidler.append(params[i]);
}
System.out.println("拼接后的字符串:"+buidler.toString());
//对拼接后的字符串进行SHA1加密
MessageDigest md = null;
String result = "";
try {
md = MessageDigest.getInstance("SHA1");
byte[] digest = md.digest(buidler.toString().getBytes());
//将字节数组转换成密文字符串
result = byteToStr(digest);
System.out.println("加密后的密文是:"+result);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//3.开发者获得加密后的字符串可与signature对比
return result != null ? (result.equalsIgnoreCase(signature)) : false;
}
/**
* 将字节数组转换为十六进制的字符串
* @param bytes
* @return
*/
private static String byteToStr(byte[] bytes){
String str = "";
for (int i = 0; i < bytes.length; i++) {
str += byteToHexStr(bytes[i]);
}
return str;
}
/**
* 将一个字节转换为十六进制的字符串
* @param b
* @return
*/
private static String byteToHexStr(byte b) {
// TODO Auto-generated method stub
char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] temp = new char[2];
temp[0] = Digit[(b>>>4)& 0x0F];
temp[1] = Digit[b & 0X0F];
String s = new String(temp);
return s;
}
}