總想自己動動手系列·3·如何讓微信公眾號和外網服務交互之通過TOKEN驗證(準備篇·1)
一、準備工作
(1)準備一個微信公眾號(對私的訂閱號或者對公的服務號)。
(2)準備一臺部署了web應用,並且已經發布出去的Linux服務器(需要說明的是:微信公眾號強烈建議使用80端口,使用其他自定義端口貌似根本不通,後面會有說明)。
先科普說明一下:
1.微信公眾號的註冊分為2種類型,這個很簡單,按照官方註冊流程按部就班地填寫基本不會出現問題。
2.剛註冊的訂閱號和公眾號是“非認證”狀態的(本人註冊的是對私的訂閱號,目前處於非認證狀態)。
3.微信官方將認證審核流程托管到了第三方機構或公司,這個是要收取服務費的,對公的服務號收費標準:300¥/次/年。具體詳細,網上是這樣回答的:
我等會就去試一下如何認證,如果認證成功了,會出一篇具體介紹如何認證對私的訂閱號的。本文註重介紹如何驗證TOKEN的。
4.用戶操作訪問微信公眾號,請求是如何處理轉發的呢?看完下面的示意圖就會明白為什麽要準備一臺自己的服務器了。
二、TOKEN驗證的流程:
先假設,我們部署在服務器上的web應用已經可以正常被外網訪問了。
(1)在微信公眾號後臺:開發-》基本設置菜單中
你以為就這麽簡單填寫就把微信服務平臺和自己的服務器web應用關聯起來了???那是不可能滴!!!這樣直接提交會報錯
先簡單介紹下途中的幾個輸入項和選擇項到底是幹嘛的!
1、URL:這個是TOKEN的驗證調取的請求url,端口要求是80或者443,我們一般用80端口。
2、Token:這個是微信服務和自己的服務之間通信的關鍵通信憑證(也可以這麽理解:開發者自定的驗證口令)。
3、EncodingAESKey:你也可以理解為通信信息加密因子,這個讓他它自動生成即可。
4、消息加解密方式:明文模式:不加解密(新手開發者建議選這個,方便開發和調試)。
(2)在自己服務器web項目中需要做調整,調整流程如下:
1、新建一個servlet.java用於處理微信服務器發送過來的Token驗證請求:
package com.xfwl.weixinToken; import java.io.IOException; import java.io.PrintWriter;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class WXServletToken extends HttpServlet { /** * 構造器 */ public WXServletToken() { super(); } /** * 銷毀操作 */ public void destroy() { super.destroy(); } /** * doGet請求處理 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * 獲取weixin請求參數 */ String signature=request.getParameter("signature"); String timestamp=request.getParameter("timestamp"); String nonce=request.getParameter("nonce"); String echostr=request.getParameter("echostr"); /** * 校驗參數是否正確 */ PrintWriter out = response.getWriter(); if(CheckUtil.checkSignature(signature, timestamp, nonce)){ //如果校驗成功,將得到的隨機字符串原路返回 out.print(echostr); } out.flush(); out.close(); } /** * doPost請求操作 */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); out.flush(); out.close(); } /** *初始化操作 */ public void init() throws ServletException {} }
2、新建一個TOKEN驗證類
1 package com.xfwl.weixinToken; 2 3 import java.security.MessageDigest; 4 import java.security.NoSuchAlgorithmException; 5 import java.util.Arrays; 6 7 /** 8 * 微信Token校驗 9 * @author Jason 10 * 11 */ 12 public class CheckUtil { 13 /** 14 * 加密規則 15 */ 16 public static final String wx_mdType="SHA1"; 17 /** 18 * 微信公眾號Token信息 19 */ 20 public static final String wx_token="*****"; 21 /** 22 * 校驗微信Token的有效性 23 * @param signature 24 * @param timestamp 時間戳 25 * @param nonce 26 * @return 27 */ 28 public static boolean checkSignature(String signature,String timestamp,String nonce){ 29 //1、定義數組存放wx_token、timestamp、nonce 30 String[] arr={wx_token,timestamp,nonce}; 31 //2、對數組進行排序 32 Arrays.sort(arr); 33 //3、生成字符串 34 StringBuffer sb=new StringBuffer(); 35 for(String s:arr){ 36 sb.append(s); 37 } 38 String temp=getSha1(sb.toString()); 39 if(temp==null){ 40 return false; 41 } 42 return temp.equals(signature); 43 } 44 public static String getSha1(String data){ 45 if(data==null || data.length()==0){ 46 return null; 47 } 48 char[] hexDigist={‘0‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘,‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘}; 49 try { 50 MessageDigest mdTemp=MessageDigest.getInstance(wx_mdType); 51 mdTemp.update(data.getBytes()); 52 byte[] md=mdTemp.digest(); 53 int j=md.length; 54 char[] buf=new char[j*2]; 55 int k=0; 56 for(int i=0;i<j;i++){ 57 byte byte0=md[i]; 58 buf[k++]=hexDigist[byte0 >>> 4 & 0xf]; 59 buf[k++]=hexDigist[byte0 & 0xf]; 60 } 61 return new String(buf); 62 63 } catch (NoSuchAlgorithmException e) { 64 System.out.println("微信公眾號TOKEN加密失敗"); 65 return null; 66 } 67 } 68 }
3、web.xml中配置請求(當然了,用註解形式也可,方式很多種,任選隨意)
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="3.0" 3 xmlns="http://java.sun.com/xml/ns/javaee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 6 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 7 <display-name></display-name> 8 <!-- 默認界面 --> 9 <welcome-file-list> 10 <welcome-file>index.jsp</welcome-file> 11 </welcome-file-list> 12 <!-- 配置過濾器 --> 13 <!-- <filter> 14 <filter-name>filter</filter-name> 15 <filter-class>com.xfwl.filter.RequestFilter</filter-class> 16 <init-param> 17 <param-name>charset</param-name> 18 <param-value>UTF-8</param-value> 19 </init-param> 20 <init-param> 21 <param-name>contentType</param-name> 22 <param-value>text/html;charset=UTF-8</param-value> 23 </init-param> 24 </filter> 25 <filter-mapping> 26 <filter-name>filter</filter-name> 27 * 代表截獲所有的請求 或指定請求/test.do /xxx.do 28 <url-pattern>/*</url-pattern> 29 </filter-mapping> --> 30 <!-- 接入微信Token驗證 --> 31 <servlet> 32 <servlet-name>WXServletToken</servlet-name> 33 <servlet-class>com.xfwl.weixinToken.WXServletToken</servlet-class> 34 </servlet> 35 36 <servlet-mapping> 37 <servlet-name>WXServletToken</servlet-name> 38 <url-pattern>/servlet/WXServletToken</url-pattern> 39 </servlet-mapping> 40 </web-app>
4、打war包,重新部署啟動
5、回到微信公眾號後臺:開發-》基本設置菜單中,輸入對應的信息,點擊提交按鈕。即可提交設置成功。
需要說明一點:圖中“IP白名單設置”,這個需要把自己服務器外網IP加上,如果你還需要使用微信公眾號的接口調試功能去測試接口的話,那麽微信公眾號平臺的IP(39.130.165.18)也需要加入白名單中。
6、到這一步:就已經完成了TOKEN的驗證了。
總想自己動動手系列·3·如何讓微信公眾號和外網服務交互之通過TOKEN驗證(準備篇·1)