說道握手,意思就是相互交流和確認通訊方式。那麼要實現與微信服務器交流協作,就必須與微信服務器進行握手,確定好交流的方式。
在官方開發文檔上寫明瞭二次開發的步驟
請仔細研讀
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請求如下:
那麼在開發服務器就要設計一個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);
}
至此就完成了微信服務器驗證