微信公众号开发的前提是我们要对公众号进行正确的配置。公众号的配置包括两部分:
- 配置白名单,只有配置了白名单我们才能获取到access_token。
- 配置服务器,正确配置服务器后,微信公众号才能将消息转到我们服务端进行处理。
配置白名单
白名单的配置比较简单。我们打开公众号,左侧找到【安全中心】,点击之后,找到【IP白名单】,点击【查看】按钮,在打开的界面,输入我们的服务器的 IP
,注意,这里输入的是 IP
。
启用服务器配置
进入微信公众号后台,选择【开发】→【基本设置】,打开如下界面
下面我们对服务器的几个参数进行将要说明:
参数说明
服务器地址(URL)
我们在启用服务器配置时,微信会通过我们配置的服务器地址,发送一条 GET
请求。
请求会携带以下参数
序号 | 参数名称 | 描述 |
---|---|---|
1 | signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
2 | timestamp | 时间戳 |
3 | nonce | 随机数 |
4 | echostr | 随机字符串 |
我们在请求中,通过检验 signature
对请求进行校验。若确认此次 GET
请求来自微信服务器,我们只需要原样返回 echostr
参数内容,代表接入成功,否则接入失败。
Token
Token
可由我们任意填写,用作生成签名(该 Token
会和接口 URL
中包含的 Token
进行比对,从而验证安全性),主要用于后期调用接口使用。
EncodingAESKey
EncodingAESKey
我们可以手动填写或随机生成,将用作消息体加解密密钥。
消息加解密方式
明文模式、兼容模式和安全模式。模式的选择与服务器配置在提交后都会立即生效,请开发者谨慎填写及选择。加解密方式的默认状态为明文模式,选择兼容模式和安全模式需要提前配置好相关加解密代码。
后台代码
后台代码,我们主要用于对 URL
的请求进行响应。
首先我们需要定义工具类,用于签名验证
SignUtil.java
/**
* 校验签名
* @param signature 签名
* @param timestamp 时间戳
* @param nonce 随机数
* @return true 成功,false 失败
*/
public static boolean checkSignature(String signature,String timestamp, String nonce){
String checktext = null;
if(null != signature){
//对Token,timestamp nonce 按字典排序
String [] paramArr = new String[] {token, timestamp, nonce};
Arrays.sort(paramArr);
//将排序后的结果拼成一个字符串
String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
//对接后的字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
checktext = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
//将加密后的字符串与signature进行对比
return checktext != null ? checktext.matches(signature.toUpperCase()) :false;
}
/**
* 将字节数组转化为16进制字符串
* @return 字符串
*/
private static String byteToStr(byte[] byteArrays) {
String str="";
for (int i = 0; i < byteArrays.length; i++){
str += byteToHexStr(byteArrays[i]);
}
return str;
}
/**
* 将字节转化为十六进制字符串
* @param myByte 字节
* @return 字符串
*/
private static String byteToHexStr(byte myByte) {
char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] tempArr = new char[2];
tempArr[0] = Digit[(myByte >>> 4)&0X0F];
tempArr[1] = Digit[myByte & 0x0F];
String str = new String(tempArr);
return str;
}
配置controller
响应URL
请求
我们在微信公众号后台配置的URL
就是我们后台对应的URL
。并且是 GET
请求。
增加WeChatController.java
@RestController
@RequestMapping("wechat")
public class WeChatController {
private final Logger logger = LoggerFactory.getLogger(WeChatController.class);
/**
* 服务器配置启用设置
* @param signature 签名
* @param timestamp 时间戳
* @param nonce 随机数
* @param echostr 随机字符串
* @return 随机字符串
* @throws Exception 异常信息
*/
@GetMapping("official")
public String authentication(@RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce, @RequestParam("echostr") String echostr) throws Exception {
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
System.out.println(echostr);
return echostr;
}
return"";
}
}
启用服务器配置
后台代码配置完成后,我们上传到外网服务器,点击启用按钮,系统提示操作成功,并且界面如下所示,代表我们配置成功。
测试
多谢谢!