微信公眾號(hào)H5頁(yè)面跳轉(zhuǎn)小程序 Java

后臺(tái)生成并返回前端所需參數(shù)

1:jsapi_ticket

jsapi_ticket是公眾號(hào)用于調(diào)用js接口的臨時(shí)票據(jù)。有效期7200秒燕偶,跟公眾號(hào)普通access_token一樣窍育,必須全局緩存起來(lái)赔桌,因?yàn)檫@個(gè)ticket獲取次數(shù)有限污筷,超過(guò)次數(shù)將無(wú)法使用证薇。

1.1獲取access_token

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

1.2獲取jsapi_ticket

https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi

2:生成簽名

簽名規(guī)則:
1泳姐、參與簽名的字段包括noncestr(隨機(jī)字符串), 有效的jsapi_ticket, timestamp(時(shí)間戳), url(當(dāng)前網(wǎng)頁(yè)的URL效拭,不包含#及其后面部分)。
2胖秒、對(duì)所有待簽名參數(shù)按照字段名的ASCII 碼從小到大排序(字典序缎患,sort()即可)后,使用URL鍵值對(duì)的格式(即key1=value1&key2=value2…)拼接成字符串(string)阎肝。
3挤渔、使用sha1加密拼接成的字符串string。
注意:字段名和字段值都要使用原值风题,不要進(jìn)行url轉(zhuǎn)義

參與的字段:

noncestr=Wm3WZYTPz0wzccnW
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
timestamp=1414587457
url=調(diào)用js接口的安全域名

2.1:校驗(yàn)簽名

https://work.weixin.qq.com/api/jsapisign

3:后端完整代碼

 public  net.sf.json.JSONObject getConfig(String url){
        //url為前端動(dòng)態(tài)入?yún)?        net.sf.json.JSONObject object = new net.sf.json.JSONObject();
        String access_token = redisStringService.get("AccessToken");
        String jsapi_ticket = redisStringService.get("JsapiTicket");
        if(StringUtils.isEmpty(access_token)){
            //獲取access_token
            String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
                    + wxConfigYml.getWxAppId()
                    + "&secret="
                    + wxConfigYml.getWxSecret();
            String result = HttpUtil.sendGet(tokenUrl);
            JSONObject accessObj = JSON.parseObject(result);
            String accessToken = accessObj.getString("access_token");
            redisStringService.put("AccessToken", accessToken, 7180);
        }
        if (StringUtils.isEmpty(jsapi_ticket)) {
            //獲取jsapi
            String jsapiStr  = HttpUtil.sendGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi");
            net.sf.json.JSONObject jsapi = net.sf.json.JSONObject.fromObject(JSON.parseObject(jsapiStr));
            jsapi_ticket = jsapi.getString("ticket");
            redisStringService.put("JsapiTicket",jsapi_ticket,7180);
        }
        //獲取簽名signature
        String noncestr = IdGen.uuid();
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        String str = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + noncestr +
                "&timestamp=" + timestamp +
                "&url=" + url;
        //sha1加密
        String signature = WechatConfig.sha1(str);
        object.put("noncestr",noncestr);
        object.put("timestamp",timestamp);
        object.put("signature",signature);
        object.put("jsapi_ticket",jsapi_ticket);
        log.info("jsapi_ticket="+jsapi_ticket);
        log.info("noncestr="+noncestr);
        log.info("timestamp="+timestamp);
        log.info("url="+url);
        log.info("signature="+signature);
        return object;
    }
3.1加密方法
    public static String sha1(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字節(jié)數(shù)組轉(zhuǎn)換為 十六進(jìn)制 數(shù)
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
3.2httpUtil
public class HttpUtil {

    private static  CloseableHttpClient httpclient = HttpClients.createDefault();

    /**
     * 發(fā)送HttpGet請(qǐng)求
     * @param url
     * @return
     */
    public static String sendGet(String url) {

        HttpGet httpget = new HttpGet(url);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httpget);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        String result = null;
        try {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                result = EntityUtils.toString(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 發(fā)送HttpPost請(qǐng)求判导,參數(shù)為map
     * @param url
     * @param map
     * @return
     */
    public static String sendPost(String url, Map<String, String> map) {
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, Consts.UTF_8);
        HttpPost httppost = new HttpPost(url);
        httppost.setEntity(entity);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httppost);
        } catch (IOException e) {
            e.printStackTrace();
        }
        HttpEntity entity1 = response.getEntity();
        String result = null;
        try {
            result = EntityUtils.toString(entity1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 發(fā)送不帶參數(shù)的HttpPost請(qǐng)求
     * @param url
     * @return
     */
    public static String sendPost(String url) {
        HttpPost httppost = new HttpPost(url);
        CloseableHttpResponse response = null;
        try {
            response = httpclient.execute(httppost);
        } catch (IOException e) {
            e.printStackTrace();
        }
        HttpEntity entity = response.getEntity();
        String result = null;
        try {
            result = EntityUtils.toString(entity);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String post(String url, String jsonString) {
        CloseableHttpResponse response = null;
        BufferedReader in = null;
        String result = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();
            httpPost.setConfig(requestConfig);
            httpPost.setConfig(requestConfig);
            httpPost.addHeader("Content-type", "application/json; charset=utf-8");
            httpPost.setHeader("Accept", "application/json");
            httpPost.setEntity(new StringEntity(jsonString, Charset.forName("UTF-8")));
            response = httpclient.execute(httpPost);
            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer sb = new StringBuffer("");
            String line = "";
            String NL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
                sb.append(line + NL);
            }
            in.close();
            result = sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != response) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

4.常見(jiàn)問(wèn)題

1、前端wx.config配置中的nonceStr字段名稱的's'是大寫(xiě)俯邓。但是后臺(tái)生成簽名的noncestr字段 的‘s'是小寫(xiě)骡楼,千萬(wàn)要注意
2、時(shí)間戳(timestamp)值要記住精確到秒稽鞭,不是毫秒鸟整。
3、生成簽名的url(使用jssdk的頁(yè)面地址朦蕴,這個(gè)頁(yè)面地址可以在瀏覽器訪問(wèn))篮条,包含“弟头?”號(hào)后面的所有參數(shù),不包含“#”號(hào)后面的值涉茧。
如果是靜默授權(quán)或者授權(quán)頁(yè)面同意授權(quán)后跳轉(zhuǎn)到的頁(yè)面赴恨,頁(yè)面路徑會(huì)添加兩個(gè)參數(shù):code和state。
即授權(quán)后跳轉(zhuǎn)頁(yè)面為http://redirect.page.com伴栓,則完整路徑為
http://redirect.page.com?code=kdijafdhjaikeiu20kaiela&state=STATE伦连。
那么生成簽名的url必須為授權(quán)后跳轉(zhuǎn)頁(yè)面的完整路徑。前端獲取這個(gè)路徑:location.href.split('#')[0]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钳垮,一起剝皮案震驚了整個(gè)濱河市惑淳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌饺窿,老刑警劉巖歧焦,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異肚医,居然都是意外死亡绢馍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)肠套,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)舰涌,“玉大人,你說(shuō)我怎么就攤上這事糠排《娉恚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我驰弄,道長(zhǎng)冕广,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任盈滴,我火速辦了婚禮涯肩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘巢钓。我一直安慰自己病苗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布症汹。 她就那樣靜靜地躺著硫朦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪背镇。 梳的紋絲不亂的頭發(fā)上咬展,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天泽裳,我揣著相機(jī)與錄音,去河邊找鬼破婆。 笑死涮总,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的祷舀。 我是一名探鬼主播瀑梗,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼裳扯!你這毒婦竟也來(lái)了抛丽?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤嚎朽,失蹤者是張志新(化名)和其女友劉穎铺纽,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體哟忍,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡狡门,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锅很。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片其馏。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖爆安,靈堂內(nèi)的尸體忽然破棺而出叛复,到底是詐尸還是另有隱情,我是刑警寧澤扔仓,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布褐奥,位于F島的核電站,受9級(jí)特大地震影響翘簇,放射性物質(zhì)發(fā)生泄漏撬码。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一版保、第九天 我趴在偏房一處隱蔽的房頂上張望呜笑。 院中可真熱鬧,春花似錦彻犁、人聲如沸叫胁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)驼鹅。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谤民,已是汗流浹背堰酿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留张足,地道東北人触创。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像为牍,于是被迫代替她去往敵國(guó)和親哼绑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容