美文网首页
微信公众号H5页面跳转小程序 Java

微信公众号H5页面跳转小程序 Java

作者: lzm_CX330 | 来源:发表于2021-07-14 09:41 被阅读0次

    后台生成并返回前端所需参数

    1:jsapi_ticket

    jsapi_ticket是公众号用于调用js接口的临时票据。有效期7200秒,跟公众号普通access_token一样,必须全局缓存起来,因为这个ticket获取次数有限,超过次数将无法使用。

    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:生成签名

    签名规则:
    1、参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分)。
    2、对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序,sort()即可)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串(string)。
    3、使用sha1加密拼接成的字符串string。
    注意:字段名和字段值都要使用原值,不要进行url转义

    参与的字段:

    noncestr=Wm3WZYTPz0wzccnW
    jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg
    timestamp=1414587457
    url=调用js接口的安全域名

    2.1:校验签名

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

    3:后端完整代码

     public  net.sf.json.JSONObject getConfig(String url){
            //url为前端动态入参
            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();
                // 字节数组转换为 十六进制 数
                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();
    
        /**
         * 发送HttpGet请求
         * @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;
        }
    
        /**
         * 发送HttpPost请求,参数为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;
        }
    
        /**
         * 发送不带参数的HttpPost请求
         * @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.常见问题

    1、前端wx.config配置中的nonceStr字段名称的's'是大写。但是后台生成签名的noncestr字段 的‘s'是小写,千万要注意
    2、时间戳(timestamp)值要记住精确到秒,不是毫秒。
    3、生成签名的url(使用jssdk的页面地址,这个页面地址可以在浏览器访问),包含“?”号后面的所有参数,不包含“#”号后面的值。
    如果是静默授权或者授权页面同意授权后跳转到的页面,页面路径会添加两个参数:code和state。
    即授权后跳转页面为http://redirect.page.com,则完整路径为
    http://redirect.page.com?code=kdijafdhjaikeiu20kaiela&state=STATE
    那么生成签名的url必须为授权后跳转页面的完整路径。前端获取这个路径:location.href.split('#')[0]

    相关文章

      网友评论

          本文标题:微信公众号H5页面跳转小程序 Java

          本文链接:https://www.haomeiwen.com/subject/euaepltx.html