1. 程式人生 > >總想自己動動手系列·3·如何讓微信公眾號和外網服務交互之通過TOKEN驗證(準備篇·1)

總想自己動動手系列·3·如何讓微信公眾號和外網服務交互之通過TOKEN驗證(準備篇·1)

utf-8 url new 加密 token alt oct ans 官方

一、準備工作

(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)