微信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;
    }




展开阅读全文

没有更多推荐了,返回首页