(微信公衆號)驗證消息的確來自微信服務器

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319

 

 

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

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

 

2.

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

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

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

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

java代碼

1.創建servlet 

2.驗證代碼

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*開發者提交信息後,微信服務器將發送GET請求到填寫的服務器地址URL上,GET請求攜帶參數如下表所示:
		參數	描述
		signature	微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。
		timestamp	時間戳
		nonce	隨機數
		echostr	隨機字符串*/
		String signature = request.getParameter("signature");
		String timestamp = request.getParameter("timestamp");
		String nonce = request.getParameter("nonce");
		String echostr = request.getParameter("echostr");
		System.out.println(signature);
		System.out.println(timestamp);
		System.out.println(nonce);
		System.out.println(echostr);
		boolean checkSignature = WxUtils.CheckSignature(signature,timestamp,nonce);
		if (checkSignature) {
			System.out.println("success");
			//
			PrintWriter writer = response.getWriter();
			writer.print(echostr);
			writer.flush();
			writer.close();
		}else {
			System.out.println("failed");
		}
	}

 WxUtils代碼

public class WxUtils {

	private static final  String Token="shxx";
	private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',  
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};  
	public static boolean CheckSignature(String signature, String timestamp, String nonce) {
		
//		1)將token、timestamp、nonce三個參數進行字典序排序 
//		2)將三個參數字符串拼接成一個字符串進行sha1加密 
//		3)開發者獲得加密後的字符串可與signature對比,標識該請求來源於微信
		String[] strs=new String[]{Token,timestamp,nonce};
		
		Arrays.sort(strs);
		
		String str=strs[0]+strs[1]+strs[2];
		
		String mysignature=sha1(str);
		return mysignature.equals(signature);
	}
	
	private static String sha1(String str) {
		
		  
        if (str == null) {  
            return null;  
        }  
        try {  
            MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); 
            messageDigest.update(str.getBytes());  
            return getFormattedText(messageDigest.digest());  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        } 
	}

	private static String getFormattedText(byte[] bytes) {
		  
        int len = bytes.length;  
        StringBuilder buf = new StringBuilder(len * 2);  
        // 把密文轉換成十六進制的字符串形式  
        for (int j = 0; j < len; j++) {  
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);  
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);  
        }  
        return buf.toString(); 
	}

		
}

 

3.在測試公衆號中進行配置

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