Spring Boot 微信-驗證伺服器有效性
阿新 • • 發佈:2019-02-06
概述
接入微信公眾平臺開發,開發者需要按照如下步驟完成:
- 在自己伺服器上,開發驗證微信驗證伺服器地址的有效性邏輯
- 在微信平臺上,填寫自己伺服器地址資訊
- 在自己伺服器上,依據微信介面文件實現業務邏輯
第一步:實現驗證伺服器地址的有效性邏輯
開發者提交資訊後,微信伺服器將傳送GET請求到填寫的伺服器地址URL上,GET請求攜帶四個引數:
引數 | 描述 |
---|---|
signature | 微信加密簽名,signature結合了開發者填寫的token引數和請求中的timestamp引數、nonce引數。 |
timestamp | 時間戳 |
nonce | 隨機數 |
echostr | 隨機字串 |
開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。
若確認此次GET請求來自微信伺服器,請原樣返回echostr引數內容,則接入生效,成為開發者成功,否則接入失敗。
加密/校驗流程如下:
- 將token、timestamp、nonce三個引數進行字典序排序
- 將三個引數字串拼接成一個字串進行sha1加密
- 開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
java程式碼:
package com.jeiker.demo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
@RestController
@RequestMapping("/wechat")
public class WeChatController {
private Logger logger = LoggerFactory.getLogger(getClass());
// URL: http://www.xxxx.com/wechat/
// Token: 此處TOKEN即為微信介面配置資訊的Token
private String TOKEN = "wechat";
/**
* 驗證微信後臺配置的伺服器地址有效性
*
* 接收並校驗四個請求引數
*
* @param signature 微信加密簽名
* @param timestamp 時間戳
* @param nonce 隨機數
* @param echostr 隨機字串
* @return echostr
*/
@GetMapping("/")
public String checkName(@RequestParam(name = "signature") String signature,
@RequestParam(name = "timestamp") String timestamp,
@RequestParam(name = "nonce") String nonce,
@RequestParam(name = "echostr") String echostr) {
logger.info("微信-開始校驗簽名");
logger.info("收到來自微信的 echostr 字串:{}", echostr);
// 加密/校驗流程如下:
// 1. 將token、timestamp、nonce三個引數進行字典序排序
// 2. 將三個引數字串拼接成一個字串進行sha1加密
// 3. 開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
// 1.排序
String sortString = sort(TOKEN, timestamp, nonce);
// 2.sha1加密
String myString = sha1(sortString);
// 3.字串校驗
if (myString != null && myString != "" && myString.equals(signature)) {
logger.info("微信-簽名校驗通過");
//如果檢驗成功原樣返回echostr,微信伺服器接收到此輸出,才會確認檢驗完成。
logger.info("回覆給微信的 echostr 字串:{}", echostr);
return echostr;
} else {
logger.error("微信-簽名校驗失敗");
return "";
}
}
/**
* 排序方法
* @param token Token
* @param timestamp 時間戳
* @param nonce 隨機數
* @return
*/
public String sort(String token, String timestamp, String nonce) {
String[] strArray = {token, timestamp, nonce};
Arrays.sort(strArray);
StringBuilder sb = new StringBuilder();
for (String str : strArray) {
sb.append(str);
}
return sb.toString();
}
/**
* 將字串進行sha1加密
*
* @param str 需要加密的字串
* @return 加密後的內容
*/
public String sha1(String str) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(str.getBytes());
byte messageDigest[] = digest.digest();
// 建立 16進位制字串
StringBuffer hexString = new StringBuffer();
// 位元組陣列轉換為 十六進位制 數
for (int i = 0; i < messageDigest.length; i++) {
String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
if (shaHex.length() < 2) {
hexString.append(0);
}
hexString.append(shaHex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
}
第二步:在微信公眾號平臺上填寫伺服器配置
登入微信公眾平臺官網後,在公眾平臺後臺管理頁面 - 開發者中心頁,點選“修改配置”按鈕,填寫伺服器地址(URL)、Token和EncodingAESKey,其中URL是開發者用來接收微信訊息和事件的介面URL。Token可由開發者可以任意填寫,用作生成簽名(該Token會和介面URL中包含的Token進行比對,從而驗證安全性)。EncodingAESKey由開發者手動填寫或隨機生成,將用作訊息體加解密金鑰。
資訊填寫好了後,點選“提交”按鈕(這裡以測試平臺為例):
微信將會發出一個GET的驗證請求到所填寫的URL上,這時後端會收到請求輸出日誌:
echostr驗證後,原樣返回給微信伺服器,就完成了伺服器地址的驗證。
伺服器日誌輸出:
微信-開始校驗簽名
收到來自微信的 echostr 字串:4868431563403787247
微信-簽名校驗通過
回覆給微信的 echostr 字串:4868431563403787247
第三步:依據介面文件實現業務邏輯
驗證URL有效性成功後即接入生效,成為開發者。
如果公眾號型別為服務號(訂閱號只能使用普通訊息介面),可以在公眾平臺網站中申請認證,認證成功的服務號將獲得眾多介面許可權,以滿足開發者需求。