微信公衆號開發-----JS-SDK使用權限簽名算法

本文只提供代碼實現,具體參數含義請先仔細閱讀微信公衆號技術文檔之JS-SDK說明文檔

jsapi_ticke

簡介:jsapi_ticket是公衆號用於調用微信JS接口的臨時票據

獲取方式:

  1. 參考以下文檔獲取access_token(有效期7200秒,開發者必須在自己的服務全局緩存access_token):https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
    具體代碼參考:微信公衆號開發----獲取access_token,定時刷新access_token

  2. 用第一步拿到的access_token 採用http GET方式請求獲得jsapi_ticket(有效期7200秒,開發者必須在自己的服務全局緩存jsapi_ticket)

    2.1相關jar包

     <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
     </dependency>
    

    2.2 創建實體(此處省去set/get方法)

    import com.alibaba.fastjson.annotation.JSONField;
    
    public class Jsapi {
    
        private int errcode;
    
        private String errmsg;
    
        private String ticket;
    
        @JSONField(name = "expires_in")
        private String expiresIn;
    
    }
    

    2.3 HttpUtil
    用於發送POST或GET請求:HttpsUtil類

    2.4 獲取ticket

    public class WechatUtil {
    
     private static Logger log = LogManager.getLogger(WechatUtil.class);
    
     private static final String JSAPI_TICKET_URL ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
    
     /**
         * 通過access_token 採用http GET方式請求獲得jsapi_ticket
         * @param accessToken
         * @return
         */
        public static String getJsapiTicket(String accessToken){
            String requestUrl = JSAPI_TICKET_URL.replace("ACCESS_TOKEN", accessToken);
            JSONObject jsonObject = HttpsUtil.request(requestUrl, "GET", null);
            Integer errCode = jsonObject.getInteger("errcode");
            if (errCode == 0){
                Jsapi jsapi= Json.getJson().parse(jsonObject.toJSONString(), Jsapi.class);
                return jsapi.getTicket();
            }else {
                log.warn("獲取jsapi_ticke失敗:"+jsonObject.toJSONString());
                return null;
            }
       	 }
       }
    

簽名算法

參與簽名的字段包括noncestr(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳), url(當前網頁的URL,不包含#及其後面部分。

生成步驟:

  1. 對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)後,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1
  2. 對string1作sha1加密,字段名和字段值都採用原始值,不進行URL 轉義。即signature=sha1(string1)
/**
     * 獲取JS-SDK簽名
     * @param url  當前網頁的URL
     * @param accessToken 
     * @return
     */
  public Map<String,String>  getJsSdkSign(String url, String accessToken){
     	 //獲取Ticket
        String jsapiTicket = WechatUtil.getJsapiTicket(accessToken);
        //時間戳和隨機字符串
        String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//隨機字符串
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//時間戳
        //將參數排序並拼接字符串
        String str = "jsapi_ticket="+jsapiTicket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;
        //將字符串進行sha1加密
        String signature = SHA1.getSHA1(str);
        Map<String,String> map = new HashMap<>();
        map.put("nonceStr",noncestr);
        map.put("timestamp",timestamp);
        map.put("signature",signature);
        return map;
    }

注:代碼中使用到的工具類請參考:消息加密工具-----SHA-1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章