转:https://blog.csdn.net/jeikerxiao/article/details/68064145
概述
接入微信公众平台开发,开发者需要按照如下步骤完成:
- 在自己服务器上,开发验证微信验证服务器地址的有效性逻辑
- 在微信平台上,填写自己服务器地址信息
- 在自己服务器上,依据微信接口文档实现业务逻辑
第一步:实现验证服务器地址的有效性逻辑
开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带四个参数:
参数 | 描述 |
---|---|
signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
开发者通过检验signature对请求进行校验(下面有校验方式)。
若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
加密/校验流程如下:
- 将token、timestamp、nonce三个参数进行字典序排序
- 将三个参数字符串拼接成一个字符串进行sha1加密
- 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
java代码:
1 package com.jeiker.demo.controller; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 import org.springframework.web.bind.annotation.GetMapping; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.bind.annotation.RequestParam; 8 import org.springframework.web.bind.annotation.RestController; 9 10 import java.security.MessageDigest; 11 import java.security.NoSuchAlgorithmException; 12 import java.util.Arrays; 13 14 @RestController 15 @RequestMapping("/wechat") 16 public class WeChatController { 17 18 private Logger logger = LoggerFactory.getLogger(getClass()); 19 20 // URL: http://www.xxxx.com/wechat/ 21 // Token: 此处TOKEN即为微信接口配置信息的Token 22 23 private String TOKEN = "wechat"; 24 25 /** 26 * 验证微信后台配置的服务器地址有效性 27 * 28 * 接收并校验四个请求参数 29 * 30 * @param signature 微信加密签名 31 * @param timestamp 时间戳 32 * @param nonce 随机数 33 * @param echostr 随机字符串 34 * @return echostr 35 */ 36 @GetMapping("/") 37 public String checkName(@RequestParam(name = "signature") String signature, 38 @RequestParam(name = "timestamp") String timestamp, 39 @RequestParam(name = "nonce") String nonce, 40 @RequestParam(name = "echostr") String echostr) { 41 42 logger.info("微信-开始校验签名"); 43 logger.info("收到来自微信的 echostr 字符串:{}", echostr); 44 45 // 加密/校验流程如下: 46 // 1. 将token、timestamp、nonce三个参数进行字典序排序 47 // 2. 将三个参数字符串拼接成一个字符串进行sha1加密 48 // 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信 49 50 // 1.排序 51 String sortString = sort(TOKEN, timestamp, nonce); 52 // 2.sha1加密 53 String myString = sha1(sortString); 54 // 3.字符串校验 55 if (myString != null && myString != "" && myString.equals(signature)) { 56 logger.info("微信-签名校验通过"); 57 //如果检验成功原样返回echostr,微信服务器接收到此输出,才会确认检验完成。 58 logger.info("回复给微信的 echostr 字符串:{}", echostr); 59 return echostr; 60 } else { 61 logger.error("微信-签名校验失败"); 62 return ""; 63 } 64 } 65 66 /** 67 * 排序方法 68 * @param token Token 69 * @param timestamp 时间戳 70 * @param nonce 随机数 71 * @return 72 */ 73 public String sort(String token, String timestamp, String nonce) { 74 String[] strArray = {token, timestamp, nonce}; 75 Arrays.sort(strArray); 76 StringBuilder sb = new StringBuilder(); 77 for (String str : strArray) { 78 sb.append(str); 79 } 80 81 return sb.toString(); 82 } 83 84 /** 85 * 将字符串进行sha1加密 86 * 87 * @param str 需要加密的字符串 88 * @return 加密后的内容 89 */ 90 public String sha1(String str) { 91 try { 92 MessageDigest digest = MessageDigest.getInstance("SHA-1"); 93 digest.update(str.getBytes()); 94 byte messageDigest[] = digest.digest(); 95 // 创建 16进制字符串 96 StringBuffer hexString = new StringBuffer(); 97 // 字节数组转换为 十六进制 数 98 for (int i = 0; i < messageDigest.length; i++) { 99 String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); 100 if (shaHex.length() < 2) { 101 hexString.append(0); 102 } 103 hexString.append(shaHex); 104 } 105 return hexString.toString(); 106 107 } catch (NoSuchAlgorithmException e) { 108 e.printStackTrace(); 109 } 110 return ""; 111 } 112 }
第二步:在微信公众号平台上填写服务器配置
登录微信公众平台官网后,在公众平台后台管理页面 - 开发者中心页,点击“修改配置”按钮,填写服务器地址(URL)、Token和EncodingAESKey,其中URL是开发者用来接收微信消息和事件的接口URL。Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。
信息填写好了后,点击“提交”按钮(这里以测试平台为例):
微信将会发出一个GET的验证请求到所填写的URL上,这时后端会收到请求输出日志:
echostr验证后,原样返回给微信服务器,就完成了服务器地址的验证。
服务器日志输出:
1 微信-开始校验签名 2 收到来自微信的 echostr 字符串:4868431563403787247 3 微信-签名校验通过 4 回复给微信的 echostr 字符串:4868431563403787247
第三步:依据接口文档实现业务逻辑
验证URL有效性成功后即接入生效,成为开发者。
如果公众号类型为服务号(订阅号只能使用普通消息接口),可以在公众平台网站中申请认证,认证成功的服务号将获得众多接口权限,以满足开发者需求。