2025年JAVA 微信公众号授权给开放平台(第三方平台)开发流程及第三方平台代公众号实现业务

JAVA 微信公众号授权给开放平台(第三方平台)开发流程及第三方平台代公众号实现业务一 开放平台账户注册及开发配置请参考我之前的文章 开发前准备工作 二 授权流程 官方文档细节比较多 我说的比较直白 1 首先 启动票据推送服务 2 接收消息 解密 验证并获取票据 保存票据 component verify ticket 3 获取第三方平台调用凭证

大家好,我是讯享网,很高兴认识大家。

一 、开放平台账户注册及开发配置请参考我之前的文章 开发前准备工作。

二、授权流程 官方文档细节比较多 我说的比较直白
(1)首先 启动票据推送服务
(2)接收消息→解密→验证并获取票据→保存票据 component_verify_ticket
(3)获取第三方平台调用凭证 component_access_token
(4)通过 component_access_token 获取预授权码 pre_auth_code
(5)通过 pre_auth_code 自建 PC授权链接 或 H5授权链接
(6)访问授权链接进入授权页面完成公众号授权;

三、授权实现 (直接贴代码)

package com.zaiyun.wechat.controller; import com.alibaba.fastjson2.JSONObject; import com..weixin.mp.aes.AesException; import com.zaiyun.common.core.controller.BaseController; import com.zaiyun.common.core.domain.AjaxResult; import com.zaiyun.common.annotation.Anonymous; import com.zaiyun.wechat.service.ThirdPartyTicketService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; / * 第三方平台调用凭证 */ @Anonymous @RestController @RequestMapping("/ticket") public class ThirdPartyTicketController extends BaseController { 
    @Resource ThirdPartyTicketService thirdPartyTicketService; private static final Logger wechatLogger = LoggerFactory.getLogger("extend-wechat"); / * 消息与事件接收配置 */ @RequestMapping("/{appId}/callback") public String callback() { 
    return "success"; } / * 启动票据推送服务 */ @PostMapping("/start/push") public AjaxResult startPushTicket() { 
    JSONObject resultObj = thirdPartyTicketService.startPushTicket(); if (resultObj.getInteger("errcode") == 0) { 
    return success(resultObj.getString("errmsg")); } return error(resultObj.toString()); } / * 验证票据 * * @param msgSignature 微信加密签名 * @param timeStamp 时间戳 * @param nonce 随机数 * @param postData 消息体 * @return 结果 * @throws AesException 异常提现 */ @PostMapping("/verify") public String componentVerifyTicket(@RequestParam("timestamp") String timeStamp, @RequestParam("nonce") String nonce, @RequestParam("msg_signature") String msgSignature, @RequestBody String postData) throws AesException { 
    try { 
    thirdPartyTicketService.componentVerifyTicket(msgSignature, timeStamp, nonce, postData); } catch (Exception e) { 
    wechatLogger.info("消息推送异常", e); e.printStackTrace(); } return "success"; } / * 获取令牌component_access_token */ @RequestMapping("/component/access/token") public AjaxResult getComponentAccessToken() { 
    JSONObject accessToken = thirdPartyTicketService.getComponentAccessToken(); return success(accessToken); } / * 获取预授权码 */ @RequestMapping("/pre/auth/code") public AjaxResult getPreAuthCode() { 
    JSONObject authCode = thirdPartyTicketService.getPreAuthCode(); return success(authCode); } / * 获取刷新令牌 * * @param authorizationCode 授权码 */ @PostMapping("/get/refresh/token") public AjaxResult getAuthorizerRefreshToken(@RequestParam("authorizationCode") String authorizationCode) { 
    JSONObject refreshToken = thirdPartyTicketService.getAuthorizerRefreshToken(authorizationCode); return success(refreshToken); } / * 获取授权账号调用令牌 * * @param authorizerAppid 授权方公众号APPID */ @PostMapping("/get/access/token") public AjaxResult getAuthorizerAccessToken(@RequestParam("authorizerAppid") String authorizerAppid) { 
    String authorizerRefreshToken = "refreshtoken@@@Gr8Kl0v10e0B8SrIBmlXfB2PXjcn4TA-RPUqkg1Iu5I"; JSONObject authorizerAccessToken = thirdPartyTicketService.getAuthorizerAccessToken(authorizerAppid, authorizerRefreshToken); return success(authorizerAccessToken); } } 

讯享网

(1)首先启动票据推送

讯享网 / * 启动票据推送服务 */ public JSONObject startPushTicket() { 
    String url = "https://api.weixin..com/cgi-bin/component/api_start_push_ticket"; HashMap<String, String> paramHeader = new HashMap<>();//请求头参数 paramHeader.put("Content-Type", "application/json"); HashMap<String, String> paramBody = new HashMap();//请求体 paramBody.put("component_appid", weixinConfig.getThirdPartyAppId()); paramBody.put("component_secret", weixinConfig.getThirdPartyAppSecret()); Object bodyParam = ConvertUtils.mapToObject(paramBody); ResponseEntity<String> responseEntity = restTemplateUtils.post(url, paramHeader, bodyParam, String.class); return JSON.parseObject(String.valueOf(responseEntity.getBody())); } 

在这里插入图片描述
讯享网

(2)验证票据并缓存 component_verify_ticket 这个很重要、非常重要、必须保存好;
Ticket的有效时间为12小时, 每隔10分钟以 POST 的方式推送,推送的加密消息如下(这是我打印的日志)

10:13:49.990 [http-nio-8090-exec-70] INFO wechat - [callback,34] - 消息与事件 <xml> <ToUserName><![CDATA[gh_138c7a]]></ToUserName> <Encrypt><![CDATA[0jexJT/7Vc4g1cwSYSuROJCpXki1j5reusgy/O43RNadB9dHFCUQ/B9XDXfIYGOrIURyP5ZbQ4SNk8c+YS0lozlIZxSzVMRPg36K74frTCFqODs0F7GDhTT1cMk13JwJBOtdpQwKR9QRrRZPU4h41WkU3M2X2aMN9eXOws/RV+VJzVzPcNXLC9Z8LnuPiz+JoXTFVM3yOIypxu1zi7cl6eh8Lookl025ZuMIc8OmxZKHW4UiyI49v8D1bc4elTt2eI5Sl4C0uYzYYIBlgfnoyStManqAL+c/MODABu0HzenvbRmpZ0iZEpGfjFghRirABvIaaT9H7ok989Fkx+J9DUAuyT0aCEcBNY3w/JP81wmi3Y9x8MM0KWyN5XIELDA6A7LZz/8BQ3NFkgMevNAO87U0z7XFo+VweOb7W01si1+Z3Z/uLqv40VFtFdGNXhYvuA1C/4u/b7y+OtJZrO14AB5y8aT3hUwpGuUTBZMcZnXYKuslEldLGmIug+bPrcSv]]></Encrypt> </xml> 

(3)接收到此消息后需要解密 官方解密文档 官方解密示例 官方解密代码示例包

讯享网 / * 验证票据 * * @param msgSignature 微信加密签名 * @param timeStamp 时间戳 * @param nonce 随机数 * @param postData 消息体 * @return 结果 * @throws AesException 异常 */ public String componentVerifyTicket(String msgSignature, String timeStamp, String nonce, String postData) throws AesException { 
    //这个类是微信官网提供的解密类,需要用到消息校验Token 消息加密Key和服务平台appid WXBizMsgCrypt pc = new WXBizMsgCrypt(weixinConfig.getThirdPartyToken(), weixinConfig.getThirdPartyKey(), weixinConfig.getThirdPartyAppId()); String xml = pc.decryptMsg(msgSignature, timeStamp, nonce, postData); Map<String, String> result = XmlToMapUtils.xmlToMap(xml);// 将xml转为map String infoType = MapUtils.getString(result, "InfoType");//消息通知类型 if (infoType.equals("unauthorized")) { 
   //取消授权 String authorizerAppid = MapUtils.getString(result, "AuthorizerAppid");//公众号APPID wechatLogger.info("取消授权APPID:" + authorizerAppid); authorizedAccountUtils.updateAuthor(authorizerAppid);//更新授权状态 } else if (infoType.equals("authorized")) { 
   //授权成功 String authorizerAppid = MapUtils.getString(result, "AuthorizerAppid");//公众号APPID wechatLogger.info("授权成功APPID:" + authorizerAppid); authorizedAccountUtils.insertOrUpdate(authorizerAppid);//更新授权数据 } else if (infoType.equals("updateauthorized")) { 
   //更新授权 String authorizerAppid = MapUtils.getString(result, "AuthorizerAppid");//公众号APPID wechatLogger.info("更新授权APPID:" + authorizerAppid); authorizedAccountUtils.insertOrUpdate(authorizerAppid);//更新授权数据 } else if (infoType.equals("component_verify_ticket")) { 
    String componentVerifyTicket = MapUtils.getString(result, "ComponentVerifyTicket"); thirdPartyUtils.saveTicketToRedis(componentVerifyTicket);//存储平台授权票据,保存ticket wechatLogger.info("componentVerifyTicket缓存成功:" + componentVerifyTicket); } else { 
    throw new RuntimeException("微信消息推送l类型未知!"); } return "success"; } 

(4)获取第三方平台调用凭证 component_access_token 这个也很重要!!!
令牌的获取是有限制的,令牌的有效期为 2 小时,做好令牌的管理在令牌快过期时(比如1小时50分)重新调用接口获取。

package com.zaiyun.wechat.utils; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.zaiyun.common.config.WeixinConfig; import com.zaiyun.common.constant.CacheConstants; import com.zaiyun.common.core.redis.RedisCache; import com.zaiyun.common.utils.ConvertUtils; import com.zaiyun.common.utils.http.RestTemplateUtils; import com.zaiyun.common.utils.spring.SpringUtils; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.HashMap; import java.util.concurrent.TimeUnit; / * 微信开放平台工具类 */ @Component public class ThirdPartyUtils { 
    @Resource WeixinConfig weixinConfig; @Resource private RestTemplateUtils restTemplateUtils; / * 微信第三方令牌缓存KEY */ private static final String TOKEN_REDIS_KEY = CacheConstants.WE_CHAT_KEY + "component_access_token." + WeixinConfig.getThirdPartyAppId(); / * 微信第三方票据缓存KEY */ private static final String TICKET_REDIS_KEY = CacheConstants.WE_CHAT_KEY + "component_verify_ticket." + WeixinConfig.getThirdPartyAppId(); / * 存储平台授权票据ticket到缓存 */ public String saveTicketToRedis(String ticketValue) { 
    SpringUtils.getBean(RedisCache.class).setCacheObject(TICKET_REDIS_KEY, ticketValue, 600, TimeUnit.MINUTES); return ticketValue; } / * 获取component_access_token */ public JSONObject getComponentAccessToken() { 
    String url = "https://api.weixin..com/cgi-bin/component/api_component_token"; HashMap<String, String> paramHeader = new HashMap<>();//请求头参数 paramHeader.put("Content-Type", "application/json"); String verifyTicket = SpringUtils.getBean(RedisCache.class).getCacheObject(TICKET_REDIS_KEY);//获取缓存 HashMap<String, String> paramBody = new HashMap();//请求体 paramBody.put("component_appid", weixinConfig.getThirdPartyAppId()); //第三方平台 appid paramBody.put("component_appsecret", weixinConfig.getThirdPartyAppSecret());//第三方平台 appsecret paramBody.put("component_verify_ticket", verifyTicket);//微信后台推送的 ticket Object bodyParam = ConvertUtils.mapToObject(paramBody); ResponseEntity<String> responseEntity = restTemplateUtils.post(url, paramHeader, bodyParam, String.class); if (responseEntity.getStatusCodeValue() == 200) { 
    return JSON.parseObject(String.valueOf(responseEntity.getBody())); } return new JSONObject(); } / * 从缓存中获取component_access_token */ public String getComponentAccessTokenToRides() { 
    String componentAccessToken = SpringUtils.getBean(RedisCache.class).getCacheObject(TOKEN_REDIS_KEY);//获取缓存 if (componentAccessToken != null) { 
    return componentAccessToken; } JSONObject resultObj = getComponentAccessToken();//重新获取component_access_token String accessToken = ""; if (!resultObj.isEmpty()) { 
    accessToken = resultObj.getString("component_access_token"); //令牌的有效期为120分钟,提前30分钟重新生成 SpringUtils.getBean(RedisCache.class).setCacheObject(TOKEN_REDIS_KEY, accessToken, 90, TimeUnit.MINUTES); } return accessToken; } / * 获取预授权码 */ public JSONObject getPreAuthCode() { 
    String url = "https://api.weixin..com/cgi-bin/component/api_create_preauthcode?access_token=" + getComponentAccessTokenToRides(); HashMap<String, String> paramHeader = new HashMap<>();//请求头参数 paramHeader.put("Content-Type", "application/json"); HashMap<String, String> paramBody = new HashMap();//请求体 paramBody.put("component_appid", weixinConfig.getThirdPartyAppId()); //第三方平台 appid Object bodyParam = ConvertUtils.mapToObject(paramBody); ResponseEntity<String> responseEntity = restTemplateUtils.post(url, paramHeader, bodyParam, String.class); return JSON.parseObject(String.valueOf(responseEntity.getBody())); } / * 获取刷新令牌 * * @param authorizationCode 微信公众号授权后携带的参数 */ public JSONObject getAuthorizerRefreshToken(String authorizationCode) { 
    String url = "https://api.weixin..com/cgi-bin/component/api_query_auth?access_token=" + getComponentAccessTokenToRides(); HashMap<String, String> paramHeader = new HashMap<>();//请求头参数 paramHeader.put("Content-Type", "application/json"); HashMap<String, String> paramBody = new HashMap();//请求体 paramBody.put("component_appid", weixinConfig.getThirdPartyAppId()); //第三方平台 appid paramBody.put("authorization_code", authorizationCode); //公众号授权后的授权码 Object bodyParam = ConvertUtils.mapToObject(paramBody); ResponseEntity<String> responseEntity = restTemplateUtils.post(url, paramHeader, bodyParam, String.class); return JSON.parseObject(String.valueOf(responseEntity.getBody())); } / * 获取授权账号调用令牌 * * @param authorizerAppid 授权方公众号APPID * @param authorizerRefreshToken 刷新令牌 */ public JSONObject getAuthorizerAccessToken(String authorizerAppid, String authorizerRefreshToken) { 
    String url = "https://api.weixin..com/cgi-bin/component/api_authorizer_token?component_access_token=" + getComponentAccessTokenToRides(); HashMap<String, String> paramHeader = new HashMap<>();//请求头参数 paramHeader.put("Content-Type", "application/json"); HashMap<String, String> paramBody = new HashMap();//请求体 paramBody.put("component_appid", weixinConfig.getThirdPartyAppId()); //第三方平台 appid paramBody.put("authorizer_appid", authorizerAppid); //授权方公众号APPID paramBody.put("authorizer_refresh_token", authorizerRefreshToken); //刷新令牌,获取授权信息时得到 Object bodyParam = ConvertUtils.mapToObject(paramBody); ResponseEntity<String> responseEntity = restTemplateUtils.post(url, paramHeader, bodyParam, String.class); if (responseEntity.getStatusCodeValue() == 200) { 
    return JSON.parseObject(String.valueOf(responseEntity.getBody())); } return new JSONObject(); } / * 从缓存获取 authorizer_access_token * * @param authorizerAppid 授权方公众号APPID * @param authorizerRefreshToken 刷新令牌 */ public String getAuthorizerAccessTokenToRedis(String authorizerAppid, String authorizerRefreshToken) { 
    String authorizerAccessTokenKey = CacheConstants.WE_CHAT_KEY + "authorizer_access_token." + authorizerAppid;//缓存Key String authorizerAccessToken = SpringUtils.getBean(RedisCache.class).getCacheObject(authorizerAccessTokenKey);//获取缓存 if (authorizerAccessToken != null) { 
    return authorizerAccessToken; } JSONObject resultObj = getAuthorizerAccessToken(authorizerAppid, authorizerRefreshToken);//重新获取authorizer_access_token String accessToken = ""; if (resultObj != null) { 
    accessToken = resultObj.getString("authorizer_access_token"); //令牌的有效期为120分钟,提前30分钟重新生成 SpringUtils.getBean(RedisCache.class).setCacheObject(authorizerAccessTokenKey, accessToken, 90, TimeUnit.MINUTES); } return accessToken; } / * 获取授权账号详情 * * @param authorizerAppid 授权的公众号或者小程序的appid * @return 结果 */ public JSONObject getAuthorizerInfo(String authorizerAppid) { 
    String url = "https://api.weixin..com/cgi-bin/component/api_get_authorizer_info?access_token=" + getComponentAccessTokenToRides(); HashMap<String, String> paramHeader = new HashMap<>();//请求头参数 paramHeader.put("Content-Type", "application/json"); HashMap<String, String> paramBody = new HashMap();//请求体 paramBody.put("authorizer_appid", authorizerAppid);//授权的公众号或者小程序的appid paramBody.put("component_appid", weixinConfig.getThirdPartyAppId());//第三方平台 appid Object bodyParam = ConvertUtils.mapToObject(paramBody); ResponseEntity<String> responseEntity = restTemplateUtils.post(url, paramHeader, bodyParam, String.class); return JSON.parseObject(String.valueOf(responseEntity.getBody())); } } 

(5)通过 component_verify_ticket、component_access_token 这两个数据就可以自建 PC授权链接、H5授权链接,用微信扫码授权;

讯享网/ * 自建PC授权链接 * * @return 结果 */ public String builtPcLink() { 
    String componentAppid = weixinConfig.getThirdPartyAppId();//第三方平台方 appid String preAuthCode = thirdPartyUtils.getPreAuthCode().getString("pre_auth_code");//预授权码 String redirectUri = "http://keduo.com/index.html#/home";//授权后回调地址 String link = "https://mp.weixin..com/cgi-bin/componentloginpage?component_appid=" + componentAppid + "&pre_auth_code=" + preAuthCode + "&redirect_uri=" + redirectUri + "&auth_type=3"; return link; } / * 自建H5授权链接 * * @return 结果 */ public String builtH5Link() { 
    String componentAppid = weixinConfig.getThirdPartyAppId();//第三方平台方 appid String preAuthCode = thirdPartyUtils.getPreAuthCode().getString("pre_auth_code");//预授权码 String redirectUri = "http://keduo.com/index.html#/home";//授权后回调地址 String link = "https://open.weixin..com/wxaopen/safe/bindcomponent?action=bindcomponent&no_scan=1&component_appid=" + componentAppid + "&pre_auth_code=" + preAuthCode + "&redirect_uri=" + redirectUri + "&auth_type=3" + "#wechat_redirect"; return link; } 

在这里插入图片描述

扫码授权后,至此公众号授权流程已完成。

四、第三方平台代公众号实现业务,首先要有这几个令牌和票据

在这里插入图片描述

(1)微信授权 (获取微信 昵称、头像、openid)
(2)获取JSSDK (jssdk 一般用于网页 支付、分享、定位等等)
(3)普通公众号的 JS SDK 的使用步骤 这个是前端的活

package com.zaiyun.wechat.controller; import com.alibaba.fastjson2.JSONObject; import com.zaiyun.common.annotation.Anonymous; import com.zaiyun.common.config.WeixinConfig; import com.zaiyun.common.core.controller.BaseController; import com.zaiyun.common.core.domain.AjaxResult; import com.zaiyun.common.core.domain.model.LoginUser; import com.zaiyun.common.oto.entity.ZyConsumerUser; import com.zaiyun.framework.web.service.TokenService; import com.zaiyun.oto.service.ZyConsumerUserService; import com.zaiyun.wechat.utils.ThirdPartyJsSdkUtils; import com.zaiyun.wechat.utils.ThirdPartyAchieveUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.beans.factory.annotation.Value; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.annotation.Resource; import javax.servlet.http.HttpSession; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Map; / * 第三方平台代公众号实现业务 */ @Anonymous @RestController @RequestMapping("/wechat") public class ThirdPartyAchieveController extends BaseController { 
    @Resource WeixinConfig weixinConfig; @Autowired private TokenService tokenService; @Resource private ThirdPartyJsSdkUtils thirdPartyJsSdkUtils; @Resource private ThirdPartyAchieveUtils thirdPartyAchieveUtils; @Autowired private ZyConsumerUserService consumerUserService; private static final Logger wechatLogger = LoggerFactory.getLogger("extend-wechat"); private String domainName;//系统域名 / * 用户同意授权,获取code * * @return 结果 */ @GetMapping("/authorize") public AjaxResult authorize(HttpServletResponse response, HttpServletRequest request, @RequestParam("token") String token, @RequestParam("url") String url) throws Exception { 
    //String domainName = request.getServerName();//客户端请求域名 LoginUser loginUser = tokenService.getLoginUserByToken(token); if (loginUser == null) { 
    return AjaxResult.error(201, "token失效"); } long userId = loginUser.getUserId(); if (url == null) { 
    return AjaxResult.error(201, "授权后重定向URL不能为空"); } HttpSession session = request.getSession(); session.setAttribute("callback", domainName + url);//将重定向地址存入session String thirdAppId = weixinConfig.getThirdPartyAppId();//第三方APPID String accountAppId = thirdPartyAchieveUtils.replaceAccountAppId(); //公众号APPID String uri = URLEncoder.encode(domainName + "/wechat/access/token", "utf-8"); String redirectUrl = "https://open.weixin..com/connect/oauth2/authorize?appid=" + accountAppId + "&redirect_uri=" + uri + "&response_type=code&scope=snsapi_userinfo&state=" + userId + "&component_appid=" + thirdAppId + "#wechat_redirect"; response.sendRedirect(redirectUrl); return success(); } / * 通过code换取网页授权access_token */ @GetMapping("/access/token") public void accessToken(HttpServletResponse response, HttpServletRequest request) throws Exception { 
    String code = request.getParameter("code"); JSONObject data = thirdPartyAchieveUtils.getAccessToken(code); String openid = data.getString("openid"); //授权用户唯一标识 String accessToken = data.getString("access_token"); //接口调用凭证 JSONObject user = thirdPartyAchieveUtils.getUserinfo(accessToken, openid); String userId = request.getParameter("state");//当前用户ID String nickname = user.getString("nickname"); String headimgurl = user.getString("headimgurl"); HttpSession session = request.getSession(); String callback = session.getAttribute("callback").toString();//从session获取重定向地址 wechatLogger.info("userId:" + userId); wechatLogger.info("callback:" + callback); wechatLogger.info("code:" + code); wechatLogger.info("openid:" + openid); wechatLogger.info("accessToken:" + accessToken); wechatLogger.info("通过code换取网页授权access_token:" + data); wechatLogger.info("user" + user); String nickname2 = new String(nickname.getBytes("ISO-8859-1"), "UTF-8"); ZyConsumerUser consumerUser = new ZyConsumerUser(); consumerUser.setUserId(Long.parseLong(userId)); consumerUser.setWeixinOpenid(openid); consumerUser.setWeixinNickname(nickname2); consumerUser.setLogo(headimgurl); consumerUserService.update(consumerUser);//更新授权微信信息 response.sendRedirect(callback);//授权后重定向 } / * 开放平台JsSdk * * @param body url 当前网页的URL,不包含#及其后面部分 * @return */ @PostMapping("/js/sdk") public AjaxResult jseSdk(@RequestBody JSONObject body) { 
    try { 
    String url = body.getString("url"); if (url == null || url.isEmpty()) { 
    return AjaxResult.error(201, "参数错误url"); } String accountAppId = thirdPartyAchieveUtils.replaceAccountAppId(); //公众号APPID String ticket = thirdPartyJsSdkUtils.getJsapiTicketToRides(accountAppId); Map<String, Object> res = thirdPartyJsSdkUtils.sign(ticket, URLDecoder.decode(url, "UTF-8")); res.put("appId", accountAppId); return success(res); } catch (Exception e) { 
    return AjaxResult.error(201, e.getMessage()); } } } 

第三方平台代公众号实现业务工具类

讯享网package com.zaiyun.wechat.utils; import java.util.*; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.io.UnsupportedEncodingException; import java.util.concurrent.TimeUnit; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.zaiyun.common.constant.CacheConstants; import com.zaiyun.common.core.redis.RedisCache; import com.zaiyun.common.utils.http.RestTemplateUtils; import com.zaiyun.common.utils.spring.SpringUtils; import com.zaiyun.common.utils.uuid.UUID; import com.zaiyun.wechat.mapper.AuthorizedAccountMapper; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import com.zaiyun.wechat.domain.AuthorizedAccount; import javax.annotation.Resource; / * 第三方平台代公众号实现业务工具类 */ @Component public class ThirdPartyJsSdkUtils { 
    @Resource private ThirdPartyUtils thirdPartyUtils; @Resource private RestTemplateUtils restTemplateUtils; @Resource private ThirdPartyAchieveUtils thirdPartyAchieveUtils; @Resource AuthorizedAccountMapper authorizedAccountMapper; / * JS-SDK jsapi_ticket 缓存KEY */ private static final String JSAPI_TICKET_KEY = CacheConstants.WE_CHAT_KEY + "authorizer_jsapi_ticket."; / * 获取jsapi_ticket */ public JSONObject getJsapiTicket() { 
    String accountAppId = thirdPartyAchieveUtils.replaceAccountAppId(); //公众号APPID AuthorizedAccount info = authorizedAccountMapper.findAuthorizerAppid(accountAppId); String authorizerAccessToken = thirdPartyUtils.getAuthorizerAccessTokenToRedis(accountAppId, info.getAuthorizerRefreshToken());//授权账号调用令牌 String url = "https://api.weixin..com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + authorizerAccessToken; ResponseEntity<String> responseEntity = restTemplateUtils.get(url, String.class); JSONObject result = JSON.parseObject(String.valueOf(responseEntity.getBody())); if (result.getInteger("errcode") == 0) { 
    return JSON.parseObject(String.valueOf(responseEntity.getBody())); } return new JSONObject(); } / * 从缓存中获取jsapi_ticket */ public String getJsapiTicketToRides(String appid) { 
    String jsapiTicket = SpringUtils.getBean(RedisCache.class).getCacheObject(JSAPI_TICKET_KEY + appid);//获取缓存 if (jsapiTicket != null) { 
    return jsapiTicket; } JSONObject resultObj = getJsapiTicket();//重新获取jsapi_ticket String jsTicket = ""; if (!resultObj.isEmpty()) { 
    jsTicket = resultObj.getString("ticket"); //有效期为120分钟,提前30分钟重新生成 SpringUtils.getBean(RedisCache.class).setCacheObject(JSAPI_TICKET_KEY + appid, jsTicket, 90, TimeUnit.MINUTES); } return jsTicket; } / * 签名 * * @param jsapi_ticket jsapi_ticket * @param url 当前网页的URL,不包含#及其后面部分 * @return 结果 */ public static Map<String, Object> sign(String jsapi_ticket, String url) { 
    Map<String, Object> ret = new HashMap<String, Object>(); String nonce_str = create_nonce_str(); String timestamp = create_timestamp(); String string1; String signature = ""; //注意这里参数名必须全部小写,且必须有序 string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str + "&timestamp=" + timestamp + "&url=" + url; 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; } private static String create_nonce_str() { 
    return UUID.fastUUID().toString(true); //return UUID.randomUUID().toString(); } private static String create_timestamp() { 
    return Long.toString(System.currentTimeMillis() / 1000); } } 

六、到此已大功告成,祝你好运!!!

小讯
上一篇 2025-03-10 16:59
下一篇 2025-02-24 21:35

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/39369.html