微信js sdk invalid signature簽名錯誤問題的解決方法分析
本文實例講述了微信js sdk invalid signature簽名錯誤問題的解決方法。分享給大家供大家參考,具體如下:
/**最近在做微信js sdk 接口調用說明*/
***相信很多人都遇見像我這樣的問題,再加上自己只能算是半個程序員,所以苦苦摸索了好久終于搞懂了。
****下面就把自己所遇見的各種問題和大家分享一下,都是自己親手實驗過的********/
一、問題說明
如果出現(xiàn) invalid signature,首先可以確定的是你的簽名算法有問題。
建議:首先查看微信官方網站給出的解決方案,鏈接為 http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
invalid signature簽名錯誤。建議按如下順序檢查:
2. 確認簽名算法正確,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 頁面工具進行校驗。也就是你自己后臺生成簽名要和微信校驗算法生成的簽名一致才可以(可能大小寫不同)。
3. 注意:
簽名生成規(guī)則如下:
參與簽名的字段包括有效的 jsapi_ticket(獲取方式詳見微信 JSSDK 文檔), noncestr (隨機字符串,由開發(fā)者隨機生成),timestamp (由開發(fā)者生成的當前時間戳), url(當前網頁的URL,不包含#及其后面部分。注意:對于沒有只有域名沒有 path 的 URL ,瀏覽器會自動加上 / 作為 path,如打開 http://qq.com 則獲取到的 URL 為 http://qq.com/)。
特別注意:你在利用參數生成簽名的時候,要對所有待簽名參數按照字段名的 ASCII 碼從小到大排序(字典序)后,使用 URL 鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串 string1。這里需要注意的是所有參數名均為小寫字符。
我的最開始的錯誤就是沒有注意到生成簽名的那幾個參數要按照key=value的樣式連接成一個字符串,然后在sha1加密生成。
/****Java寫的參數拼接算法***/
String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket,
"timestamp=" + timestamp, "noncestr=" + nonce, "url=" + jsurl };
Arrays.sort(paramArr);
// 將排序后的結果拼接成一個字符串
String content = paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2])
.concat("&"+paramArr[3]);
System.out.println("拼接之后的content為:"+content);
4. 確認config中nonceStr(js中駝峰標準大寫S), timestamp與用以簽名中的對應noncestr, timestamp一致。
5. 確認url是頁面完整的url(請在當前頁面alert(location.href.split('#')[0])確認),包括'http(s)://'部分,以及'?'后面的GET參數部分,但不包括'#'hash后面的部分。
6. 確認 config 中的 appid 與用來獲取 jsapi_ticket 的 appid 一致。
7. 確保一定緩存access_token和jsapi_ticket。
8. 確保你獲取用來簽名的url是動態(tài)生成的,動態(tài)頁面可參見實例代碼中php的實現(xiàn)方式。如果是html的靜態(tài)頁面在前端通過ajax將url傳到后臺簽名,前端需要用js獲取當前頁面除去'#'hash部分的鏈接(可用location.href.split('#')[0]獲?。驗轫撁嬉坏┓窒?,微信客戶端會在你的鏈接末尾加入其它參數,如果不是動態(tài)獲取當前鏈接,將導致分享后的頁面簽名失敗。
錯誤2、每次后臺網頁更新之后,微信訪問效果沒有出來。
問題:手機端,網頁緩沖導致。
解決方案:重啟手機,再試一下。
錯誤3、微信分享接口,可以在自己的網頁上面自定義一個按鈕,當用戶點擊的時候完成分享。
問題:我最開始也是這樣想的,后來發(fā)現(xiàn),原來不是這樣的,只有當你用微信客戶端打開,在最上面右邊的 “分享到朋友圈”按鈕按的時候效果才會出來。
錯誤4、微信圖像接口 permission denied
首先查看微信給出的錯誤說明:該公眾號沒有權限使用這個JSAPI(部分接口需要認證之后才能使用)。
說明:只要通過了公眾號認證,都不會有問題。
檢查對象:如果出現(xiàn)這個說明程序上基本上不會有問題 微信后臺已經返回了數據。
第一、要檢查 你的config 文件中相應的 jsapilist 是否包含了該接口喲。
/***用戶打開頁面的時候就加載**/
$(document).ready(function(){
initPage();
});
function initPage() {
//alert(window.location.href);/***用于獲得當前連接url用**/
/***用戶點擊分享到微信圈后加載接口接口*******/
$.post("http://******",{"url":window.location.href},function(data,status){
data=eval("("+data+")");
wx.config({
debug: false,
appId: 'wxa7a1ad4cc5116437',
timestamp:data.timestamp,
nonceStr:data.noncestr,
signature:data.signature,
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'hideOptionMenu',
]
});
wx.ready(function(){
wx.hideOptionMenu();/***隱藏分享菜單****/
});
});
};
說明:這一塊我是通過寫一個方法,然后用戶用AJax 的post 獲得這樣的請求,然后參數是URL。
二、實例說明
獲得jsticket
public static String getjsTicket(String accesstoken) {
String appid = "XXXXXXX";
String appsecret = "XXXX";
String result = "";
String url = js_ticketurl.replace("ACCESS_TOKEN", accesstoken);
System.out.println("查看js_url:" + url);
// 調用接口返回json字符串
JSONObject jsonObject = httpRequest(url, "GET", "");
System.out.println("查看紅的js_ticket:" + jsonObject.toString());
if (null != jsonObject) {
result = jsonObject.getString("ticket");// 獲得ticket
System.out.println("ticket為:" + result);
}
return result;
}
獲得signature
// 獲得js signature
public static String getSignature(String jsapi_ticket, String timestamp,
String nonce, String jsurl) throws IOException {
/****
* 對 jsapi_ticket、 timestamp 和 nonce 按字典排序 對所有待簽名參數按照字段名的 ASCII
* 碼從小到大排序(字典序)后,使用 URL 鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串
* string1。這里需要注意的是所有參數名均為小寫字符。 接下來對 string1 作 sha1 加密,字段名和字段值都采用原始值,不進行
* URL 轉義。即 signature=sha1(string1)。
* **如果沒有按照生成的key1=value&key2=value拼接的話會報錯
*/
String[] paramArr = new String[] { "jsapi_ticket=" + jsapi_ticket,
"timestamp=" + timestamp, "noncestr=" + nonce, "url=" + jsurl };
Arrays.sort(paramArr);
// 將排序后的結果拼接成一個字符串
String content = paramArr[0].concat("&"+paramArr[1]).concat("&"+paramArr[2])
.concat("&"+paramArr[3]);
System.out.println("拼接之后的content為:"+content);
String gensignature = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
// 對拼接后的字符串進行 sha1 加密
byte[] digest = md.digest(content.toString().getBytes());
gensignature = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
// 將 sha1 加密后的字符串與 signature 進行對比
if (gensignature != null) {
return gensignature;// 返回signature
} else {
return "false";
}
// return (String) (ciphertext != null ? ciphertext: false);
}
/**
* 將字節(jié)數組轉換為十六進制字符串
*
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 將字節(jié)轉換為十六進制字符串
*
* @param mByte
* @return
*/
private static String byteToHexStr(byte mByte) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
String s = new String(tempArr);
return s;
}
希望本文所述對大家微信程序設計有所幫助。
相關文章
有關IntelliJ IDEA中LeetCode插件配置問題
這篇文章主要介紹了關于IntelliJ IDEA中LeetCode插件配置問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08
Java中BigDecimal類與int、Integer使用總結
這篇文章主要給大家介紹了關于Java中BigDecimal類與int、Integer使用的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-07-07
Java使用JDBC實現(xiàn)Oracle用戶認證的方法詳解
這篇文章主要介紹了Java使用JDBC實現(xiàn)Oracle用戶認證的方法,結合實例形式分析了java使用jdbc實現(xiàn)數據庫連接、建表、添加用戶、用戶認證等操作流程與相關注意事項,需要的朋友可以參考下2017-08-08
詳解Spring Security中獲取當前登錄用戶的詳細信息的幾種方法
本文主要介紹了詳解Spring Security中獲取當前登錄用戶的詳細信息的幾種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-05-05
SpringBoot使用Feign進行服務間通信的實現(xiàn)示例代碼
Feign是一個開源的Java HTTP客戶端,可以幫助我們在SpringBoot應用中快速構建和使用HTTP客戶端,方便實現(xiàn)服務間的通信,本文就來介紹一下SpringBoot使用Feign進行服務間通信的實現(xiàn)示例代碼,感興趣的可以了解一下2024-01-01

