1. 程式人生 > >微信JSSDK分享介面中wx.config 出現invalid signature問題的解決辦法

微信JSSDK分享介面中wx.config 出現invalid signature問題的解決辦法



先看下面的JSP程式碼:

String rand =  StringUtil.getUUID();  //隨機字串
//String timestamp = Long.toString(new Date().getTime());
String timestamp = Long.toString(System.currentTimeMillis() / 1000);// Long.toString(new Date().getTime());
 
String url = "http://m.kuaixuetuan.com/portal/apps/wd/vip/product.jsp?rowId="+proRowId;
String sign =  CommonUtil.createShareSign( "jiacheng",rand,timestamp,url);

   wx.config({
        debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
        appId: '<%=appId%>', // 必填,公眾號的唯一標識
  nonceStr: '<%=rand%>', // 必填,生成簽名的隨機串
        signature: '<%=sign%>',// 必填,簽名,見附錄1
  timestamp: <%=Long.parseLong(timestamp)%>, // 必填,生成簽名的時間戳
        jsApiList: [

  'checkJsApi',
        'onMenuShareTimeline',
        'onMenuShareAppMessage',
        'onMenuShareQQ',
        'onMenuShareWeibo',
        'hideMenuItems',
        'showMenuItems',
        'hideAllNonBaseMenuItem',
        'showAllNonBaseMenuItem',
        'translateVoice',
        'startRecord',
        'stopRecord',
        'onRecordEnd',
        'playVoice',
        'pauseVoice',
        'stopVoice',
        'uploadVoice',
        'downloadVoice',
        'chooseImage',
        'previewImage',
        'uploadImage',
        'downloadImage',
        'getNetworkType',
        'openLocation',
        'getLocation',
        'hideOptionMenu',
        'showOptionMenu',
        'closeWindow',
        'scanQRCode',
        'chooseWXPay',
        'openProductSpecificView',
        'addCard',
        'chooseCard',
        'openCard'

  ] 
   });

其中時間戳timestamp可以用 Long.toString(System.currentTimeMillis() / 1000); 獲取,timestamp的長度是10位數字;

url是當前網頁的url地址。

我今天從上午除錯到傍晚,呼叫wx.config一直出現invalid signature的問題,最後發現問題還是出現在計算簽名的演算法上。仔細閱讀了微信文件,發現自己誤將token當做jsapi_ticket了,實際上要做兩次微信介面呼叫,第一次呼叫獲取access_token,第二次呼叫根據access_token計算jsapi_ticket,下面是自己寫的CommonUtil類中關於計算簽名的演算法:

public static String createShareSign(String accountId,String rand,String timestamp,String url) throws Exception
 {
  //首先獲得一個accessToken
  String token = WeixinAccessTokenUtil.getAccessToken(accountId);//自己寫的獲取快取access_token,大家可按自己的方式獲取accessToken
  //根據token獲取jsapi
  String jsapiUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
  jsapiUrl = jsapiUrl.replace("ACCESS_TOKEN", token);
  //
  JSONObject jsonObject = httpsRequest(jsapiUrl, "GET", null);//呼叫jsapi介面獲取jsapi_ticket
  String jsapiTicket = jsonObject.getString("ticket");
  log.info("返回的jsapiticket::"+jsapiTicket);
  log.info(jsonObject.toString());
  String string1="";
   String signature="";
        //System.out.println("SHA1簽名 :"+str);
   string1 = "jsapi_ticket=" + jsapiTicket +
                 "&noncestr=" + rand +
                 "&timestamp=" + timestamp +
                 "&url=" + url;
       System.out.println(string1);
       try
       {
           MessageDigest crypt = MessageDigest.getInstance("SHA-1");
           crypt.reset();
           crypt.update(string1.getBytes("UTF-8"));
           signature = byteToHex(crypt.digest());
       }
       catch (NoSuchAlgorithmException e)
       {
           e.printStackTrace();
       }
       catch (UnsupportedEncodingException e)
       {
           e.printStackTrace();
       }
      
        System.out.println("簽名1:"+signature);
      // System.out.println("簽名2:"+  SHA1Util.encode(string1) );
  return signature;
  
 }
 private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }