Spring Boot 微信-验证服务器有效性【转】

转:https://blog.csdn.net/jeikerxiao/article/details/68064145

概述

接入微信公众平台开发,开发者需要按照如下步骤完成:

  1. 在自己服务器上,开发验证微信验证服务器地址的有效性逻辑
  2. 在微信平台上,填写自己服务器地址信息
  3. 在自己服务器上,依据微信接口文档实现业务逻辑

第一步:实现验证服务器地址的有效性逻辑

开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带四个参数:

参数 描述
signature

微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。

timestamp 时间戳
nonce 随机数
echostr 随机字符串

开发者通过检验signature对请求进行校验(下面有校验方式)。

若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。

加密/校验流程如下:

  1. 将token、timestamp、nonce三个参数进行字典序排序
  2. 将三个参数字符串拼接成一个字符串进行sha1加密
  3. 开发者获得加密后的字符串可与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有效性成功后即接入生效,成为开发者。

如果公众号类型为服务号(订阅号只能使用普通消息接口),可以在公众平台网站中申请认证,认证成功的服务号将获得众多接口权限,以满足开发者需求。

猜你喜欢

转载自www.cnblogs.com/thyHome/p/9215114.html