微信公衆號開發-接入驗證

        在上一篇文章中,樓主介紹了在微信公衆號開發過程中的接入概述,同時實現了接入概述中的第一步,服務器相關配置,同時做了穿透測試,實現了外網用戶訪問本地應用服務的可行性。

        本篇文章將介紹接入概述中的第二步,驗證消息的確來自微信服務器

         在開發文檔中,對第二步的驗證,微信官方文檔給出了這樣的描述,樓主這裏直接把它貼過來。

         開發者提交信息後,微信服務器將發送GET請求到填寫的服務器地址URL上,GET請求攜帶參數如下表所示:

參數 描述
signature 微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。
timestamp 時間戳
nonce 隨機數
echostr 隨機字符串

        開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。若確認此次GET請求來自微信服務器,請原樣返回echostr參數內容,則接入生效,成爲開發者成功,否則接入失敗。加密/校驗流程如下:

1)將token、timestamp、nonce三個參數進行字典序排序

2)將三個參數字符串拼接成一個字符串進行sha1加密

3)開發者獲得加密後的字符串可與signature對比,標識該請求來源於微信

具體實現代碼如下所示:

package service;

import java.security.MessageDigest;
import java.util.Arrays;

public class WxService {
	
	private static final String TOKEN = "wxtest1";
	
	/**
	 * 簽名驗證
	 * @param signature
	 * @param timestamp
	 * @param nonce
	 * @return
	 */
	
	public static boolean check(String signature, String timestamp, String nonce) {
		
		/**
		 * 簽名驗證規則
		 * 1)將token、timestamp、nonce三個參數進行字典序排序 
		 * 2)將三個參數字符串拼接成一個字符串進行sha1加密 
		 * 3)開發者獲得加密後的字符串可與signature對比,標識該請求來源於微信
		 */
		
		//將token、timestamp、nonce三個參數進行字典序排序 	
		String[] str = new String[]{TOKEN, timestamp, nonce};
		Arrays.sort(str);
		
		//將三個參數字符串拼接成一個字符串進行sha1加密 
		String str1 = str[0] + str[1] + str[2];
	    String encodeSignature = sha1(str1);
		
	    //開發者獲得加密後的字符串可與signature對比,標識該請求來源於微信
		return encodeSignature.equalsIgnoreCase(signature);
	}
	
	/**
	 * sha1加密
	 */
	public static String sha1(String str) {
		try {
			//獲取一個加密對象
			MessageDigest md = MessageDigest.getInstance("sha1");
			//將獲取到的對象加密
			byte[] digest = md.digest(str.getBytes());
			
			char[] chars = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
			StringBuilder builder = new StringBuilder();
			//處理加密結果
			for(byte b:digest) {
				//高4位與15相與
				builder.append(chars[(b>>4)&15]);
				//低4位直接相與
				builder.append(chars[b&15]);
			}
			return builder.toString();
		}catch(Exception e) {
			System.out.println("異常類型爲:" + e);
		}
		return null;
	}
}

在處理邏輯過程中添加校驗方法的調用,具體代碼如下所示:



import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import service.WxService;

/**
 * Servlet implementation class WxServlet
 */
@WebServlet("/wx")
public class WxServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public WxServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * 
     * 參數	描述
     * signature	微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。
     * timestamp	時間戳
     * nonce	隨機數
     * echostr	隨機字符串
     * 
     */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
//		response.getWriter().append("Served at: ").append(request.getContextPath());
		String signature = request.getParameter("signature");
		String timestamp = request.getParameter("timestamp");
		String nonce = request.getParameter("nonce");
		String echostr = request.getParameter("echostr");

		System.out.println("signature:" + signature);
		System.out.println("timestamp:" + timestamp);
		System.out.println("nonce:" + nonce);
		System.out.println("echostr:" + echostr);
		
		//驗證簽名
		if(WxService.check(signature, timestamp, nonce)) {
//			System.out.println("校驗成功");
			PrintWriter writer = response.getWriter();
			writer.print(echostr);
			writer.flush();
			writer.close();
		}else {
			System.out.println("校驗失敗");
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
//		doGet(request, response);
		System.out.println("post");
	}

}

 調用完成之後開始啓動測試,測試結果如下所示:

控制檯返回的結果如下所示: 

 至此,在接入概述中,前兩步已經完成,後續就是依賴接口文檔實現業務邏輯,這將會在後續的博客中陸續推出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章