在开发基于微信公众号或小程序的应用时,微信 Access Token 是调用微信 API 接口的必要凭证。为了避免在多个服务中频繁地请求微信服务器,造成不必要的资源浪费和性能瓶颈,通常会采用中控服务器统一获取和刷新微信 Access Token 的方式。本文将介绍如何在中控服务器中实现统一获取和刷新微信 Access Token 的方案。
先上代码:
//ip鉴权,只有指定的ip才可以进行获取token String remoteAddr = request.getHeader("X-Forwarded-For"); if (StrUtil.isBlank(remoteAddr)) { remoteAddr = request.getRemoteAddr(); }else { remoteAddr = remoteAddr.split(SymbolConstant.COMMA)[0]; } log.info("访问地址 ====> {}", remoteAddr); String passUrl = commonProperties.getPassUrl(); if (StrUtil.isBlank(passUrl)) { log.info("没有配置允许访问的ip!!!!!"); return ""; } if (!passUrl.contains(remoteAddr)) { log.info("该ip: {} 不允许访问,运行访问的ip为 {}", remoteAddr, passUrl); return ""; } //============================================ //token已经存在,直接返回 if (redisUtil.hasKey(RedisConstant.WX_TOKEN)) { //计算该token的实时过期时间,实现逻辑是:缓存获取token的时间,然后与现在的时间进行对比 Date now = new Date(); Object obj = redisUtil.get(RedisConstant.WX_TOKEN); JSONObject res = JSONUtil.parseObj(obj); String createTime = res.getStr("createTime"); DateTime createDate = DateUtil.parse(createTime, "yyyy-MM-dd HH:mm:ss"); res.put("expires_in", Long.valueOf(res.getStr("expires_in")) - (Math.abs(now.getTime() - createDate.getTime()) / 1000)); res.remove("createTime"); return res.toString(); } //请求微信的接口 String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + commonProperties.getDsAppId() + "&secret=" + commonProperties.getDsSecret(); String body = HttpUtil.createGet(url).execute().body(); if (StrUtil.isBlank(body)) { log.info("response body is null"); return null; } try { //解析token,并缓存 JSONObject res = JSONUtil.parseObj(body); log.info("微信返回的结果: {}", res.toString()); String accessToken = res.getStr("access_token"); String expiresIn = res.getStr("expires_in"); if (!StrUtil.isAllNotBlank(accessToken, expiresIn)) { log.info("返回的参数有误~ {}", res.toString()); return null; } //缓存获取token的时间 res.put("createTime", DateUtil.format(new Date(),"yyyy-MM-dd HH:mm:ss")); redisUtil.set(RedisConstant.WX_TOKEN, res, Long.valueOf(expiresIn) - (5 * 60)); res.remove("createTime"); return res.toString(); } catch (Exception e) { log.error("获取token失败", e); } return null;
中控服务器通常是一个独立的服务,负责管理微信 Access Token 的获取和刷新。其他业务服务需要调用微信 API 时,可以向中控服务器请求 Access Token,而无需直接与微信服务器通信。这样一来,可以避免多个业务服务频繁请求微信服务器,降低对微信服务器的压力。
在中控服务器中,可以通过向微信服务器发送 HTTP 请求获取 Access Token,并将其缓存起来,以备后续使用。为了确保 Access Token 的有效性,需要定时刷新缓存中的 Access Token。以下是获取和缓存微信 Access Token 的基本流程:
由于微信 Access Token 的有效期较短(通常为两小时),需要定时刷新缓存中的 Access Token,以确保业务服务始终能够获取到有效的 Access Token。可以通过定时任务或者定时触发器实现 Access Token 的定时刷新,例如每隔一段时间(如1小时55分钟)自动向微信服务器请求新的 Access Token,并更新缓存中的值。
在中控服务器中管理微信 Access Token 时,需要考虑安全性问题。建议采用 HTTPS 协议进行通信,确保数据传输的安全性。另外,可以通过限制访问来源 IP 或者添加访问权限验证等方式,保障中控服务器的安全性。
通过中控服务器统一获取和刷新微信 Access Token,可以有效地降低对微信服务器的请求次数,提高应用的性能和稳定性。同时,合理的缓存策略和定时刷新机制能够确保业务服务始终能够获取到有效的 Access Token,从而保障应用的正常运行。在实际应用中,可以根据业务需求和安全考虑,灵活地调整和优化中控服务器的实现方案。