微信公眾號開發-服務器配置
因為公司網頁需要調用公眾號的api,所以特做記錄
由於微信服務器獲取的IP地址不固定,所以需要調用api,就需要配置服務器地址
1.微信公眾平台配置
要進行服務器配置的話首先登入微信公眾平台,總步驟如下:
- 登入微信公眾平台 ,在左側菜單欄最下方子菜單找到 開發–基本配置
2.進入基本配置
官網文檔:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
接入概述
接入微信公眾平台開發,開發者需要按照如下步驟完成:
1、填寫服務器配置
2、驗證服務器地址的有效性
3、依據接口文檔實現業務邏輯
下面詳細介紹這3個步驟。
第一步:填寫服務器配置
登錄微信公眾平台官網后,在公眾平台官網的開發-基本設置頁面,勾選協議成為開發者,點擊“修改配置”按鈕,填寫服務器地址(URL)、Token和EncodingAESKey,其中URL是開發者用來接收微信消息和事件的接口URL。Token可由開發者可以任意填寫,用作生成簽名(該Token會和接口URL中包含的Token進行比對,從而驗證安全性)。EncodingAESKey由開發者手動填寫或隨機生成,將用作消息體加解密密鑰。
同時,開發者可選擇消息加解密方式:明文模式、兼容模式和安全模式。模式的選擇與服務器配置在提交后都會立即生效,請開發者謹慎填寫及選擇。加解密方式的默認狀態為明文模式,選擇兼容模式和安全模式需要提前配置好相關加解密代碼,詳情請參考消息體簽名及加解密部分的文檔 。
第二步:驗證消息的確來自微信服務器
開發者提交信息后,微信服務器將發送GET請求到填寫的服務器地址URL上,GET請求攜帶參數如下表所示:
參數 | 描述 |
---|---|
signature | 微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。 |
timestamp | 時間戳 |
nonce | 隨機數 |
echostr | 隨機字符串 |
我使用的是java驗證
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; /** * zh on 2020/5/18. */ public class SignUtil { private static String token = "WeChatToken";// 與微信公眾號上的token一致,是服務器令牌(token),這里寫什么。服務器就填什么 /** * 校驗簽名 * * @param signature 簽名 * @param timestamp 時間戳 * @param nonce 隨機數 * @return 布爾值 */ 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.equals(signature.toUpperCase()) : false; } /** * 將字節數組轉化我16進制字符串 * * @param byteArrays 字符數組 * @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[] tampArr = new char[2]; tampArr[0] = Digit[(myByte >>> 4) & 0X0F]; tampArr[1] = Digit[myByte & 0X0F]; String str = new String(tampArr); return str; } }
調用:
** * zh on 2020/5/18. */ @RestController @RequestMapping(path = "wxPublic") @CrossOrigin /* 驗證公眾號token */ public class WxPublicController { private static final Logger log = LoggerFactory.getLogger(TempMaterialController.class); @GetMapping(value = "serial") public String checkSign(HttpServletRequest request, HttpServletResponse response) { try { String signature = request.getParameter("signature"); String timestamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); String echostr = request.getParameter("echostr"); log.info("本身" + signature); if (SignUtil.checkSignature(signature, timestamp, nonce)) { return echostr; } } catch (Exception e) { log.error("驗證公眾號token失敗", e); } return null; } }
注意你的的項目發布的服務器地址(必須是已備案的域名,端口必須是80或443)+項目名+接口名 :意思是你的項目必須發布在一台外網可以訪問到的服務器上,且發布的端口必須是80或443,