一、填寫服務器配置
首先我們需要在微信公眾平台上填寫服務器配置
重點內容
服務器地址URL(一定要外網能訪問的到)
在我們提交配置的時候,微信會發送GET請求到URL上,
並會攜帶 signature,timestamp,nonce,echostr 四個參數,
我的URL是 http://www.baidu.com/wxpublic/verify_wx_token,
也就是 域名 + 接口 路徑,至於怎么驗證,我會在下面說到
signature: 微信加密簽名,signature結合了我們自己填寫的token參數和請求中的timestamp參數、nonce參數
timestamp: 時間戳
nonce: 字符串
echostr: 隨機字符串
令牌Token
Token 可由我們自行定義,主要作用是參與生成簽名,與微信請求的簽名進行比較
消息加解密密鑰EncodingAESKey
EncodingAESKey 可由我們自行定義或隨機生成,主要作用是參與接收和推送給公眾平台消息的加解密
消息加解密方式
此處我選擇的是安全模式,大家可以根據自己的具體需求,選擇相應的模式
二、代碼驗證
@RequestMapping("/wxpublic/verify_wx_token")
@Response
public String verifyWXToken(HttpServletRequest request) throws AesException {
String msgSignature = request.getParameter("signature");
String msgTimestamp = request.getParameter("timestamp");
String msgNonce = request.getParameter("nonce");
String echostr = request.getParameter("echostr");
if (WXPublicUtils.verifyUrl(msgSignature, msgTimestamp, msgNonce)) {
return echostr;
}
return null;
}
WXPublicUtils
public class WXPublicUtils {
/**
* 驗證Token
* @param msgSignature 簽名串,對應URL參數的signature
* @param timeStamp 時間戳,對應URL參數的timestamp
* @param nonce 隨機串,對應URL參數的nonce
*
* @return 是否為安全簽名
* @throws AesException 執行失敗,請查看該異常的錯誤碼和具體的錯誤信息
*/
public static boolean verifyUrl(String msgSignature, String timeStamp, String nonce)
throws AesException {
// 這里的 WXPublicConstants.TOKEN 填寫你自己設置的Token就可以了
String signature = SHA1.getSHA1(WXPublicConstants.TOKEN, timeStamp, nonce);
if (!signature.equals(msgSignature)) {
throw new AesException(AesException.ValidateSignatureError);
}
return true;
}
}
AesException
@SuppressWarnings("serial")
public class AesException extends Exception {
public final static int OK = 0;
public final static int ValidateSignatureError = -40001;
public final static int ParseXmlError = -40002;
public final static int ComputeSignatureError = -40003;
public final static int IllegalAesKey = -40004;
public final static int ValidateAppidError = -40005;
public final static int EncryptAESError = -40006;
public final static int DecryptAESError = -40007;
public final static int IllegalBuffer = -40008;
public final static int EncodeBase64Error = -40009;
public final static int DecodeBase64Error = -40010;
public final static int GenReturnXmlError = -40011;
private int code;
private static String getMessage(int code) {
switch (code) {
case ValidateSignatureError:
return "簽名驗證錯誤";
case ParseXmlError:
return "xml解析失敗";
case ComputeSignatureError:
return "sha加密生成簽名失敗";
case IllegalAesKey:
return "SymmetricKey非法";
case ValidateAppidError:
return "appid校驗失敗";
case EncryptAESError:
return "aes加密失敗";
case DecryptAESError:
return "aes解密失敗";
case IllegalBuffer:
return "解密后得到的buffer非法";
case EncodeBase64Error:
return "base64加密錯誤";
case DecodeBase64Error:
return "base64解密錯誤";
case GenReturnXmlError:
return "xml生成失敗";
default:
return null;
}
}
public int getCode() {
return code;
}
public AesException(int code) {
super(getMessage(code));
this.code = code;
}
}
SHA1
public class SHA1 {
/**
* 用SHA1算法驗證Token
*
* @param token 票據
* @param timestamp 時間戳
* @param nonce 隨機字符串
* @return 安全簽名
* @throws AesException
*/
public static String getSHA1(String token, String timestamp, String nonce) throws AesException {
try {
String[] array = new String[]{token, timestamp, nonce};
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < 3; i++) {
sb.append(array[i]);
}
String str = sb.toString();
// SHA1簽名生成
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (Exception e) {
e.printStackTrace();
throw new AesException(AesException.ComputeSignatureError);
}
}
}
---------------------
作者:Gene Xu
來源:CSDN
原文:https://blog.csdn.net/goodbye_youth/article/details/80590831
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!