微信二次開發第一彈 —— 與微信握手

說道握手,意思就是相互交流和確認通訊方式。那麼要實現與微信服務器交流協作,就必須與微信服務器進行握手,確定好交流的方式。

在官方開發文檔上寫明瞭二次開發的步驟
請仔細研讀
http://mp.weixin.qq.com/wiki/17/2d4265491f12608cd170a95559800f2d.html

相信看完了這個文檔,應該對二次開發流程有所瞭解。

進入主題:如何實現與微信握手
(走到這裏,默認你擁有了對外開放80端口的服務器,已經認證的微信號<測試號也可以>,如果沒達到要求請自行解決)

首先,微信服務器驗證開發服務器有效的方法就是向開發服務器發送一個Get請求,如果這個請求有效並返回了指定的文本即驗證通過,否則驗證失敗。

那麼這個Get請求是如何構成?它是由4個參數構成.

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

在此假設80端口服務器地址爲 http://wx.xxx.com/meeting,那麼可以清楚的知道微信服務器發送的Get請求如下:

http://wx.xxx.com/meeting?signature=2db495ee2f1e7c34172f369d54bd2a1d43223dd0&timestamp=1430991401&nonce=244249404&echostr=xxxxxx

那麼在開發服務器就要設計一個Get方法接收4個參數

@ResponseBody
@RequestMapping(value="/meeting",method = RequestMethod.GET)
public String Meeting(@RequestParam String signature,
                    @RequestParam String timestamp,
                    @RequestParam String nonce,
                    @RequestParam String echostr){

    /*驗證是否是微信服務器*/

}

如何驗證微信服務器傳過來的參數呢?
官方文檔要求對傳過來的參數進行排序並進行SHA1編碼,考慮到這個是驗證方法,所以可以寫成通用方法如下

public static String isWxService(String signature,String timestamp,String nonce,String echostr){        
    List<String> params = new ArrayList<String>();  
    //此處獲取公衆號的Token
    params.add(wxConfig.getTOKEN());  
    params.add(timestamp);  
    params.add(nonce);  

    //1. 將token、timestamp、nonce三個參數進行字典序排序  
    Collections.sort(params, new Comparator<String>() {

        public int compare(String o1, String o2) {  
            return o1.compareTo(o2);  
        }  

    });  

    //2. 將三個參數字符串拼接成一個字符串進行sha1加密  
    String temp = SHA1.encode(params.get(0) + params.get(1) + params.get(2));  
    if (temp.equals(signature)) {
        return echostr;
    }

    return "";
}

/** 
* Takes the raw bytes from the digest and formats them correct. 
* 
* @param bytes the raw bytes from the digest. 
* @return the formatted bytes. 
*/  
private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',  
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};  

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

public static String encode(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);  
    }  
}  

上面代碼包含了排序與SHA1加密,僅僅實現微信服務器驗證代碼如下

@ResponseBody
@RequestMapping(value="/meeting",method = RequestMethod.GET)
public String Meeting(@RequestParam String signature,
                    @RequestParam String timestamp,
                    @RequestParam String nonce,
                    @RequestParam String echostr){

    /*驗證是否是微信服務器*/
    return isWxService(signature,timestamp,nonce,echostr);
}

至此就完成了微信服務器驗證

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