微信JS-SDK使用权限签名java代码(方法直接复制可用)


前言

官方开发参考文档
微信JS-SDK 是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。使用之前需要向服务器索要签名,本文结合官方开发文档使用java实现计算签名。


一、获取access_token

在这里插入图片描述

上代码

/**
     * 获取AccessToken
     *
     * @return
     */
    private String getAccessToken() {
        String errMsg = "微信获取accessToken失败";
        String redisKey = "HLMCheckup:HhyWechat:AccessToken";
        String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
        String appid = "";
        String secret = "";
        //去redis里取accessToken
        String accessToken = redisCache.getCacheObject(redisKey);
        if (StringUtils.isEmpty(accessToken)) {
            //redis里的accessToken已过期,重新计算
            String param = "grant_type=client_credential&appid=" + appid + "&secret=" + secret;
            String resultJsonStr = HttpUtils.sendGet(accessTokenUrl, param);
            if (StringUtils.isEmpty(resultJsonStr)) {
                log.error(errMsg);
                throw new ServiceException(errMsg);
            }
            JSONObject resultJsonObject = JSONObject.parseObject(resultJsonStr);
            Object errcode = resultJsonObject.get("errcode");
            if (errcode != null) {
                log.error("微信获取accessToken失败,errcode:{},msg:{}", errcode, resultJsonObject.get("errmsg"));
                throw new ServiceException(errMsg);
            }
            accessToken = resultJsonObject.getObject("access_token", String.class);
            Long expires = resultJsonObject.getObject("expires_in", Long.class);
            redisCache.setCacheObject(redisKey, accessToken);
            redisCache.expire(redisKey, expires);
        }
        return accessToken;
    }

二、获取jsapi_ticket

在这里插入图片描述

private String getTicket() {
        String ticketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        String ticketRedisKey = "HLMCheckup:HhyWechat:JsApi";
        String ticket = redisCache.getCacheObject(ticketRedisKey);
        if (StringUtils.isNotEmpty(ticket)) {
            return ticket;
        }
        String param = "access_token=" + getAccessToken() + "&type=jsapi";
        String resultJsonStr = HttpUtils.sendGet(ticketUrl, param);
        if (StringUtils.isEmpty(resultJsonStr)) {
            throw new ServiceException("获取jsapi失败");
        }
        JSONObject resultJsonObject = JSONObject.parseObject(resultJsonStr);
        Integer errcode = resultJsonObject.getObject("errcode", Integer.class);
        if (errcode == 0) {
            ticket = resultJsonObject.getObject("ticket", String.class);
            Long expires = resultJsonObject.getObject("expires_in", Long.class);
            redisCache.setCacheObject(ticketRedisKey, ticket);
            redisCache.expire(ticketRedisKey, expires);
        } else {
            log.error("获取jsapi失败:{}", resultJsonObject.getObject("errmsg", String.class));
            throw new ServiceException("获取jsapi失败");
        }
        return ticket;
    }
   

三、准备签名算法的四个参数并进行sha1加密

在这里插入图片描述

	/**
     * 获取js-sdk签名
     *
     * @param url 调用方传递的参数
     * @return
     */
    public String getJsSdkSign(String url) throws NoSuchAlgorithmException {
        Map paramMap = new HashMap();
        paramMap.put("url", url);
        paramMap.put("noncestr", generateRandomString(););
        paramMap.put("jsapi_ticket", getTicket());
        paramMap.put("timestamp", System.currentTimeMillis() /1000);
        String requestParam = formatUrlMap(paramMap, false, false);
        return  SHA1Util.sha1(requestParam);
    }
    
	/**
     * 获取16位随机字符串
     * @return
     */
	public  String generateRandomString() {
        String upperCaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder sb = new StringBuilder(16);
        Random random = new Random();
        for (int i = 0; i < 16; i++) {
            sb.append(upperCaseLetters.charAt(random.nextInt(upperCaseLetters.length())));
        }
        return sb.toString();
    }
	/**
     * @description: 将参数按照字段名排序
     */
    public static String formatUrlMap(Map<String, Object> paraMap, boolean urlEncode, boolean keyToLower) {
        String buff = "";
        Map<String, Object> tmpMap = paraMap;
        try {
            List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(tmpMap.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
            Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
                @Override
                public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造URL 键值对的格式
            StringBuilder buf = new StringBuilder();
            for (Map.Entry<String, Object> item : infoIds) {
                if (StringUtils.isNotBlank(item.getKey())) {
                    String key = item.getKey();
                    Object val = item.getValue();
                    if (urlEncode) {
                        val = URLEncoder.encode(val.toString(), "utf-8");
                    }
                    if (keyToLower) {
                        buf.append(key.toLowerCase() + "=" + val);
                    } else {
                        buf.append(key + "=" + val);
                    }
                    buf.append("&");
                }
            }

            buff = buf.toString();
            if (buff.isEmpty() == false) {
                buff = buff.substring(0, buff.length() - 1);
            }
        } catch (Exception e) {
            return null;
        }
        return buff;
    }

sha1加密工具类,上代码

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHA1Util {
    public static String sha1(String input) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(input.getBytes());
        byte[] output = md.digest();
        StringBuilder sb = new StringBuilder();
        for (byte b : output) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值