java版微信公众号开发(八)获取jsapi_ticket,生产JS-SDK签名

jsapi_ticket是公众号用于调用微信JS接口的临时票据。只用正确的签名才能使用JS调用微信接口,小编在这里整理一个一套完整的获取方法。废话不多说,直接上干货。

    //import java.security.MessageDigest;
     /*** 获取位置信息签名
     * @Author FM_南风
     * @Date 2024/3/12 15:52
     **/
    @Override
    public JsonResult getSign(String url) {
        logger.info("获取微信授权ticket,用于前端获取信息:===>【{}】", url);
        //url必须是调用JS接口页面的完整URL。
        String ticket = TokenUtil.getTicket(redis, APP_ID, APP_SECRET);
        logger.info("ticket:===>【{}】", ticket);
        //生成11位时间戳
        long time11 = System.currentTimeMillis() / 1000;
        String timestamp = String.valueOf(time11);
        //生成16位随机字符串
        String nonce = StringUtil.create16String();
        String string1 = "jsapi_ticket=" + ticket + "&noncestr=" + nonce + "&timestamp=" + timestamp + "&url=" + url;
        // 2.1这里利用了hutool的加密工具类
        logger.info("使用sha1加密前的细信息:===>【{}】", string1);
        String signature = "";
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = PswUtil.encryptSha1(crypt.digest());
        } catch (Exception e) {
            logger.info(e.getMessage());
        }
        logger.info("signature:===>【{}】", signature);
        Map<String, String> map = new HashMap<>();
        map.put("signature", signature);
        map.put("timestamp", timestamp);
        map.put("nonce", nonce);
        map.put("url", url);
        map.put("ticket", ticket);
        logger.info("将生成sign信息返回给前端:===>【{}】", map);
        return JsonResult.ok(map);
    }

其中用到了工具类:TokenUtil.getTicket

public class TokenUtil {
    private static final Logger logger = LoggerFactory.getLogger(TokenUtil.class);
    
    /*** 
     * 获取微信ticket签名
     **/
    public static String getTicket(redia, String appId, String appSecret) {
        String ticket  = redis.getTicket();
        if(ticket != null && !ticket.isEmpty()){
            return ticket;
        }
        String token ="token";//你自己的token获取逻辑
        String result = HttpUtil.doGet(String.format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi", token));
        logger.info("获取ticket返回结果:===>【{}】", result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        int code = jsonObject.getIntValue("errcode");
        ticket = jsonObject.getString("ticket");
        if (code == 40014 || code == 40001 || code == 42001) {
            logger.info("微信access_token过期或无效,需要重新获取token并生成ticket");
            redis.deleteWxToken();
            logger.info("删除微信access_token,递归调用生成ticket");
             return  getTicket(redis, appId, appSecret);
        }
        redis.saveTicket(ticket);
        return ticket;
    }
}
HttpUtil.doGet
public class HttpUtil {

    /**
     * get方式的http请求
     * @param httpUrl 请求地址
     * @return 返回结果
     */
    public static String doGet(String httpUrl) {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        String result = null;// 返回结果字符串
        try {
            // 创建远程url连接对象
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开一个连接,强转成httpURLConnection类
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接方式:get
            connection.setRequestMethod("GET");
            // 设置连接主机服务器的超时时间:15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取远程返回的数据时间:60000毫秒
            connection.setReadTimeout(60000);
            // 发送请求
            connection.connect();
            // 通过connection连接,获取输入流
            if (connection.getResponseCode() == 200) {
                inputStream = connection.getInputStream();
                // 封装输入流,并指定字符集
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
                // 存放数据
                StringBuilder sbf = new StringBuilder();
                String temp;
                while ((temp = bufferedReader.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append(System.getProperty("line.separator"));
                }
                result = sbf.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();// 关闭远程连接
            }
        }
        return result;
    }
}
StringUtil.create16String();
public class StringUtil {
    /*** 
     * 生成16位随机大小写加数字的字符串
     **/
    public static String create16String(){
        String a = "ZXCVBNMASDFGHJKLQWERTYUIOPzxcvbnmasdfghjklqwertyuiop0123456789";
        StringBuilder con = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 16; i++) {
            con.append(a.charAt(random.nextInt(62)));
        }
        return con.toString();
    }
}
PswUtil.encryptSha1
public class PswUtil {
    
    /*** 
     * 生成微信sha1方法签名
     **/
    public static String encryptSha1(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
}

这就是一个完整的获取jsapi_ticket生成签名的过程。

注意事项

  1. 签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。

  2. 签名用的url必须是调用JS接口页面的完整URL。

  3. 出于安全考虑,开发者必须在服务器端实现签名的逻辑
     

  • 30
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值