微信自定义分享获取签名

2 篇文章 0 订阅

  在上一篇文章中介绍了微信自定义分享对页面进行的配置。想要实现页面的这些配置,需要后台获取相应的值传到页面中。

  那么那些值都是如何获取的呢?

  如需获取页面中的值,APPID是公众号的唯一标识(存储在数据库中),可通过accountID(公众号id)来得到。timestamp ,生成签名的时间戳和nonceStr签名生成的字符串可以这样获取:

<span style="font-size:18px;"><span style="font-size:18px;"> private static String create_nonce_str() {
        return UUID.randomUUID().toString();//随机字符串
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);//时间戳
    }</span></span>

  最后的signatrue签名需要签名机制来生成。

  签名机制:

  1、通过access_token采用http Get方式的请求获取jsapi_ticket(有效期为7200秒)

  2、通过得到的jsapi_ticket和随机字符串noncestr,时间戳timestamp,当前网页的URL(不包含#及其后面部分),对这几个参数按照ASCII码从小到大排序(字典序),使用URL键值对的格式(key1=value1&key2=value2…)拼接成字符串string1,这里所有的参数均为小写字符。

  3、然后对string1进行SHA1加密。字段名和字段值都采用原始值,不进行URL转义。

<span style="font-size:18px;"><span style="font-size:18px;"> public Map<String, String> test(HttpServletRequest requesturl, String accountid) throws Exception {
        String ticket = getWeiXinTicket(accountid);

        // 注意 URL 一定要动态获取,不能 hardcode
        String url = requesturl.getRequestURL().toString();
        String domain = ResourceUtil.getConfigByName("domain");
        String param = requesturl.getQueryString();
        url = url + "?" + param;
        Map<String, String> ret = sign(ticket, url);
        for (Map.Entry entry : ret.entrySet()) {
            System.out.println(entry.getKey() + ", " + entry.getValue());
        }
        ret.put("appId", appId);
        return ret;
    }

    public static Map<String, String> sign(String jsapi_ticket, String url) {
        Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                "&noncestr=" + nonce_str +
                "×tamp=" + 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();
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }
 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;
    }
</span></span>

<span style="font-size:18px;"><span style="font-size:18px;">  public String getWeiXinTicket(String accountid) throws Exception {
        String token = getAccessToken(accountid);

//        if(null==apiticket){
//            URL url1=new URL("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken.getToken()+"&type=jsapi");
//        String urll = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=accessToken&type=jsapi";
        String urll = WeixinUtil.share_url;

        String requestUrll = urll.replace("accessToken", token);
        JSONObject json1 = httpRequest(requestUrll, "GET", null);
        String ticket = (String) json1.get("ticket");
        return ticket;
        // 断开连接

    }</span></span>
<span style="font-size:18px;"><span style="font-size:18px;">  public String getAccessToken(String accountId) throws Exception {
        String token = "";
//        WeixinAccountServiceImpl impl=new WeixinAccountServiceImpl();
        WeixinAccountEntity account = weixinAccountService.findUniqueByProperty(WeixinAccountEntity.class, "id", accountId);

        appId = account.getAccountappid();

        if (!account.getAuthorizationType().equalsIgnoreCase("0")) {
            return this.getAuthorizerAccessToken(account.getId());
        }

        token = account.getAccountaccesstoken();
        if (token != null && !"".equals(token)) {
            // 判断有效时间 是否超过2小时
            java.util.Date end = new java.util.Date();
            java.util.Date start = new java.util.Date(account.getAddtoekntime()
                    .getTime());
            if ((end.getTime() - start.getTime()) / 1000 / 3600 >= 2) {
                // 失效 重新获取
                String requestUrl = WeixinUtil.access_token_url.replace(
                        "APPID", account.getAccountappid()).replace(
                        "APPSECRET", account.getAccountappsecret());
                JSONObject jsonObject = WeixinUtil.httpRequest(requestUrl,
                        "GET", null);
                if (null != jsonObject) {
                    try {
                        token = jsonObject.getString("access_token");
                        // 重置token
                        account.setAccountaccesstoken(token);
                        // 重置事件
                        account.setAddtoekntime(new Date());
                        weixinAccountService.saveOrUpdate(account);
                    } catch (Exception e) {
                        token = null;
                        // 获取token失败
                        String wrongMessage = "获取token失败 errcode:{} errmsg:{}"
                                + jsonObject.getInt("errcode")
                                + jsonObject.getString("errmsg");
                    }
                }
            } else {
                return account.getAccountaccesstoken();
            }
        } else {
            String requestUrl = WeixinUtil.access_token_url.replace("APPID",
                    account.getAccountappid()).replace("APPSECRET",
                    account.getAccountappsecret());
            JSONObject jsonObject = WeixinUtil.httpRequest(requestUrl, "GET",
                    null);
            if (null != jsonObject) {
                try {
                    token = jsonObject.getString("access_token");
                    // 重置token
                    account.setAccountaccesstoken(token);
                    // 重置事件
                    account.setAddtoekntime(new Date());
                    weixinAccountService.saveOrUpdate(account);
                } catch (Exception e) {
                    token = null;
                    // 获取token失败
                    String wrongMessage = "获取token失败 errcode:{} errmsg:{}"
                            + jsonObject.getInt("errcode")
                            + jsonObject.getString("errmsg");
                }
            }
        }
        return token;
    }</span></span>
<span style="font-size:18px;"> public String getWeiXinTicket(String accountid) throws Exception {
        WeixinAccountEntity account = weixinAccountService.findUniqueByProperty(WeixinAccountEntity.class, "id", accountid);
        String ticket="";
        ticket=account.getJsapiTicket();

        if (ticket != null && !"".equals(ticket)) {
            // 判断有效时间 是否超过2小时
            java.util.Date end = new java.util.Date();
            java.util.Date start = new java.util.Date(account.getJsapiTicketTime()
                    .getTime());
            if ((end.getTime() - start.getTime()) / 1000 / 3600 >= 2) {
                // 失效 重新获取
                String urll = WeixinUtil.share_url;
                String token = getAccessToken(accountid);
                String requestUrll = urll.replace("accessToken", token);
                JSONObject json1 = httpRequest(requestUrll, "GET", null);
                if (null != json1) {
                    try {
                        ticket  = (String) json1.get("ticket");
                        // 重置ticket
                        account.setJsapiTicket(ticket);
                        // 重置事件
                        account.setJsapiTicketTime(new Date());
                        weixinAccountService.saveOrUpdate(account);
                    } catch (Exception e) {
                        token = null;
                        // 获取token失败
                        String wrongMessage = "获取ticket失败 errcode:{} errmsg:{}"
                                + json1.getInt("errcode")
                                + json1.getString("errmsg");
                    }
                }
            } else {
                ticket= account.getJsapiTicket();
            }
        } else {
            String urll = WeixinUtil.share_url;
            String token = getAccessToken(accountid);
            String requestUrll = urll.replace("accessToken", token);
            JSONObject json1 = httpRequest(requestUrll, "GET", null);
            if (null != json1) {
                try {
                    ticket  = (String) json1.get("ticket");
                    // 重置ticket
                    account.setJsapiTicket(ticket);
                    // 重置事件
                    account.setJsapiTicketTime(new Date());
                    weixinAccountService.saveOrUpdate(account);
                } catch (Exception e) {
                    token = null;
                    // 获取token失败
                    String wrongMessage = "获取ticket失败 errcode:{} errmsg:{}"
                            + json1.getInt("errcode")
                            + json1.getString("errmsg");
                }
            }
        }</span>


<span style="font-size:18px;"><span style="font-size:18px;"> public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
        JSONObject jsonObject = null;
        StringBuffer buffer = new StringBuffer();
        try {
            // 创建SSLContext对象,并使用我们指定的信任管理器初始化
            TrustManager[] tm = {new MyX509TrustManager()};
            SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            // 从上述SSLContext对象中得到SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();

            URL url = new URL(requestUrl);
            HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
            httpUrlConn.setSSLSocketFactory(ssf);

            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod(requestMethod);

            if ("GET".equalsIgnoreCase(requestMethod))
                httpUrlConn.connect();

            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式,防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }

            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            jsonObject = JSONObject.fromObject(buffer.toString());
            // jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            org.jeecgframework.core.util.LogUtil.info("Weixin server connection timed out.");
        } catch (Exception e) {
            org.jeecgframework.core.util.LogUtil.info("https request error:{}" + e.getMessage());
        }
        return jsonObject;
    }</span></span>

<span style="font-size:18px;"><span style="font-size:18px;"> public String getAuthorizerAccessToken(String id) {
        String ret = "";
        if (StringUtils.isBlank(id)) {
            return ret;
        }
        WeixinAccountEntity account = weixinAccountService.findUniqueByProperty(WeixinAccountEntity.class, "id", id);
//        WeixinAccountEntity account = this.getEntity(WeixinAccountEntity.class, id);
        if (account.getAuthorizationType().equalsIgnoreCase("0")) {
            logger.info(String.format("weixin account %s 没有使用第三方授权", id));
        } else {
            String token = account.getAuthorizerAccessToken();
            if (StringUtils.isNotBlank(token) && account.getAuthorizerAccessTokenExpireTime().after(new Date())) {
                ret = token;
            } else {
                String platformId = account.getOpenPlatformId();
                WeixinOpenPlatformEntity platform = weixinOpenPlatformService.getEntity(WeixinOpenPlatformEntity.class, platformId);
                String componentAccessToken = getComponentAccessToken(id);
                String componentAppId = platform.getAppId();
                String authorizerAppId = account.getAccountappid();
                String refreshToken = account.getAuthorizerRefreshToken();
                String requestUrl = API_AUTHORIZER_TOKEN.replace("COMPONENT_ACCESS_TOKEN", componentAccessToken);
                JSONObject postData = new JSONObject();
                postData.put("component_appid", componentAppId);
                postData.put("authorizer_appid", authorizerAppId);
                postData.put("authorizer_refresh_token", refreshToken);
                JSONObject obj = WeixinUtil.httpRequest(requestUrl, "POST", postData.toString());
                if (obj.containsKey("authorizer_access_token")) {
                    String authorizerAccessToken = obj.getString("authorizer_access_token");
                    String authorizerRefreshToken = obj.getString("authorizer_refresh_token");
                    int expiresIn = obj.getInt("expires_in");
                    Date expireTime = addTime(new Date(), expiresIn, Calendar.SECOND);
                    ret = authorizerAccessToken;
                    account.setAuthorizerAccessToken(authorizerAccessToken);
                    account.setAuthorizerRefreshToken(authorizerRefreshToken);
                    account.setAuthorizerAccessTokenExpireTime(expireTime);
                    weixinAccountService.saveOrUpdate(account);
                } else {
                    logger.info(String.format("获取authorizer_access_token失败: %s", obj.toString()));
                }
            }
        }

        return ret;
    }

    public String getComponentAccessToken(String id) {
        String ret = "";
        WeixinAccountEntity account = weixinAccountService.findUniqueByProperty(WeixinAccountEntity.class, "id", id);
        if (account.getId().equalsIgnoreCase("-1")) {
            logger.info("找不到当前登录微信公众号");
            return ret;
        } else {
            if (account.getAuthorizationType().equalsIgnoreCase("1") || account.getAuthorizationType().equalsIgnoreCase("2")) {
                String platformId = account.getOpenPlatformId();
                ret = this.getComponentAccessToken(platformId, "temp");
            } else {
                logger.info(String.format("公众号未采用第三方授权. id:%s, authorizationType:%s, accountId:%s", account.getId(), account.getAuthorizationType(), account.getWeixin_accountid()));
            }
        }

        return ret;
    }

    public String getComponentAccessToken(String platformId, String temp) {
        String ret = "";
        if (StringUtils.isBlank(platformId)) {
            return ret;
        }

        WeixinOpenPlatformEntity entity = systemService.get(WeixinOpenPlatformEntity.class, platformId);
        Date now = new Date();
        if (StringUtils.isNotBlank(entity.getComponentAccessToken()) && entity.getTokenExpireTime().after(now)) {
            ret = entity.getComponentAccessToken();
        } else {
            JSONObject postData = new JSONObject();
            postData.put("component_appid", entity.getAppId());
            postData.put("component_appsecret", entity.getAppSecret());
            postData.put("component_verify_ticket", entity.getComponentVerifyTicket());
            JSONObject obj = WeixinUtil.httpRequest(API_COMPONENT_TOKEN, "POST", postData.toString());
            if (obj.containsKey("component_access_token")) {
                String token = obj.getString("component_access_token");
                Integer expiresIn = obj.getInt("expires_in");
                ret = token;
                Date expireTime = addTime(new Date(), expiresIn, Calendar.SECOND);
                entity.setComponentAccessToken(token);
                entity.setTokenExpireTime(expireTime);
                systemService.save(entity);
            } else {
                logger.info(String.format("获取component_access_token失败. %s", obj.toString()));
            }
        }

        return ret;
    }

    private Date addTime(Date current, int value, int unit) {
        Calendar c = Calendar.getInstance();
        c.setTime(current);
        c.add(unit, value);
        return c.getTime();
    }</span></span>




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: 在进行微信定义分享时,需要在页面中引入微信 JS-SDK,然后通过 wx.config() 方法进行配置,最后调用 wx.onMenuShareAppMessage() 方法进行分享。 以下是一段示例代码: ``` <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> <script> wx.config({ debug: false, // 开启调试模式 appId: '你的 AppID', // 必填,公众号的唯一标识 timestamp: '时间戳', // 必填,生成签名的时间戳 nonceStr: '随机字符串', // 必填,生成签名的随机串 signature: '签名', // 必填,签名 jsApiList: [ 'onMenuShareAppMessage' // 必填,需要使用的 JS 接口列表 ] }); wx.ready(function() { // 在这里调用 wx.onMenuShareAppMessage() 方法 wx.onMenuShareAppMessage({ title: '分享标题', // 分享标题 desc: '分享描述', // 分享描述 link: '分享链接', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致 imgUrl: '分享图标', // 分享图标 success: function() { // 用户确认分享后执行的回调函数 }, cancel: function() { // 用户取消分享后执行的回调函数 } }); }); </script> ``` 在上面的代码中,wx.config() 方法用于配置 ### 回答2: 以下是一个基本的微信定义分享的代码示例: ```javascript // 在页面加载完成后初始化微信SDK document.addEventListener("DOMContentLoaded", function() { // 引入微信JS SDK var script = document.createElement("script"); script.src = "https://res.wx.qq.com/open/js/jweixin-1.6.0.js"; script.onload = function() { // 初始化微信SDK wx.config({ appId: "YOUR_APP_ID", // 微信公众号的 app ID timestamp: "TIMESTAMP", // 该页面的生成签名的时间戳 nonceStr: "NONCESTR", // 该页面的生成签名的随机串 signature: "SIGNATURE", // 该页面的签名 jsApiList: ["updateAppMessageShareData", "updateTimelineShareData"] // 需要使用的微信JS SDK接口 }); }; document.head.appendChild(script); }); // 微信配置成功后的操作 wx.ready(function() { // 获取当前页面的URL var url = location.href.split("#")[0]; // 自定义分享的内容 var shareData = { title: "自定义分享标题", desc: "自定义分享描述", link: url, imgUrl: "分享缩略图的URL" }; // 更新“分享给朋友”按钮及分享到朋友圈的信息 wx.updateAppMessageShareData(shareData); wx.updateTimelineShareData(shareData); }); ``` 上述代码中,需要替换的部分有: `YOUR_APP_ID`:微信公众号的 app ID,可在公众号后台获取。 `TIMESTAMP`:生成签名的时间戳,可以通过后台接口获取。 `NONCESTR`:生成签名的随机串,可以通过后台接口获取。 `SIGNATURE`:该页面的签名,可通过后台接口获取。 `标题`、`描述`、`URL`、`分享缩略图的URL`:根据实际情况自定义分享的内容。 以上代码实现了在页面加载完成后初始化微信SDK,并在微信配置成功后自定义分享的标题、描述、URL和缩略图。在用户点击“分享给朋友”或“分享到朋友圈”按钮时,会触发相应的分享操作。 ### 回答3: 下面是一个简单的使用微信定义分享功能的代码示例: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>微信定义分享</title> <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> <script> wx.config({ appId: '你的App ID', timestamp: '生成签名的时间戳', nonceStr: '生成签名的随机串', signature: '签名', jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData'] }); wx.ready(function () { // 自定义分享到朋友圈 wx.updateTimelineShareData({ title: '分享标题', link: '分享链接', imgUrl: '分享图标', success: function () { // 分享成功回调 alert("分享到朋友圈成功"); } }); // 自定义分享给好友 wx.updateAppMessageShareData({ title: '分享标题', desc: '分享描述', link: '分享链接', imgUrl: '分享图标', success: function () { // 分享成功回调 alert("分享给好友成功"); } }); }); </script> </head> <body> <!-- 页面内容 --> </body> </html> ``` 请确保在更新`appId`、`timestamp`、`nonceStr`和`signature`时提供正确的数值。同时,也要替换分享的标题、链接、图片等信息,以满足你自己的需求。分享成功后,你可以根据需要添加一些额外的操作或通知用户分享结果。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值