微信开放平台第三方授权(第二篇)

1.授权步骤开发

参考牛人的文档,按照步骤集成。

  1. 配置微信第三方平台中的授权事件接收URL:http://my-domain/notify/receive_ticket
  2. 配置微信第三方平台中的公众号消息与事件接收URL http://my-domain/notify/APPID/callback
  3. 首次启动后需要 等待收到 微信推送的 component_verify_ticket 后才可以使用接口 (在第三方平台创建审核通过后,微信服务器每隔10分钟会向第三方的消息接收地址推送一次component_verify_ticket,用于获取第三方平台接口调用凭据)
  4. 浏览器访问:http://my-domain/api/auth/goto_auth_url_show 点击 go 跳转到微信授权页面 扫码授权

 2.开发步骤

增加依赖

<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-open</artifactId><version>3.3.0</version>
</dependency>
  • 授权获取component_verify_ticket方式
package com.test.wechat.controller;import com.test.wechat.consts.WechatOpenConst;
import com.test.wechat.service.WechatOpenService;
import com.test.wechat.util.ServletUtil;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;import java.util.concurrent.TimeUnit;/*** @author <a href="https://github.com/007gzs">007</a>*/
@RestController
@RequestMapping("/wechatOpen/platform")
public class WechatOpenNotifyController {private final Logger logger = LoggerFactory.getLogger(this.getClass());@Autowiredprotected WechatOpenService wxOpenService;@Autowiredprivate ValueOperations<String, Object> valOps;@AutowiredRedisTemplate redisTemplate;@RequestMapping("/receive_ticket")public Object receiveTicket(String key,@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp,@RequestParam("nonce") String nonce, @RequestParam("signature") String signature,@RequestParam(name = "encrypt_type", required = false) String encType,@RequestParam(name = "msg_signature", required = false) String msgSignature) throws WxErrorException {logger.info("\n接收微信请求:[key=[{}],[signature=[{}], encType=[{}], msgSignature=[{}],"+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",key,signature, encType, msgSignature, timestamp, nonce, requestBody);ServletUtil.setKey(key);if (!StringUtils.equalsIgnoreCase("aes", encType)|| !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");}// aes加密的消息WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody,wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString());String componentVerifyTicket=inMessage.getComponentVerifyTicket();if(redisTemplate.getExpire(WechatOpenConst.OPEN_PLATFORM_TICKET + key)<10*60) {valOps.set(WechatOpenConst.OPEN_PLATFORM_TICKET + key, componentVerifyTicket, 60 * 60 * 12, TimeUnit.SECONDS);}wxOpenService.getComponentAccessToken(key, componentVerifyTicket);try {String out = wxOpenService.getWxOpenComponentService().route(inMessage);logger.debug("\n组装回复信息:{}", out);} catch (WxErrorException e) {logger.error("receive_ticket", e);}return "success";}@RequestMapping("{appId}/callback")public Object callback(String key,@RequestBody(required = false) String requestBody,@PathVariable("appId") String appId,@RequestParam("signature") String signature,@RequestParam("timestamp") String timestamp,@RequestParam("nonce") String nonce,@RequestParam("openid") String openid,@RequestParam("encrypt_type") String encType,@RequestParam("msg_signature") String msgSignature) {logger.info("\n接收微信请求:[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}],"+ " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody);ServletUtil.setKey(key);if (!StringUtils.equalsIgnoreCase("aes", encType)|| !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");}String out = "";// aes加密的消息WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody,wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);logger.info("\n消息解密后内容为:\n{} ", inMessage.toString());// 全网发布测试用例if (StringUtils.equalsAnyIgnoreCase(appId, "wx6c317d44449bfd92", "wx570bc396a51b8ff8")) {try {if (StringUtils.equals(inMessage.getMsgType(), "text")) {if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) {out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback").fromUser(inMessage.getToUser()).toUser(inMessage.getFromUser()).build(),wxOpenService.getWxOpenConfigStorage());} else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) {String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api";WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build();wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage);}} else if (StringUtils.equals(inMessage.getMsgType(), "event")) {WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build();wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage);}} catch (WxErrorException e) {logger.error("callback", e);}}else{WxMpXmlOutMessage outMessage = wxOpenService.route(inMessage);if(outMessage != null){out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(outMessage, wxOpenService.getWxOpenConfigStorage());}}return out;}
}
  • 编写授权代码-授权地址
package com.test.wechat.controller;import com.test.wechat.service.WechatOpenService;
import com.test.wechat.util.ServletUtil;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author <a href="https://github.com/007gzs">007</a>*/
@Controller
@RequestMapping("/wechatOpen/open/api")
public class WechatOpenApiController {private final Logger logger = LoggerFactory.getLogger(getClass());@Autowiredprivate WechatOpenService wxOpenService;@Autowiredprivate ValueOperations<String, Object> valOps;@GetMapping("/auth/goto_auth_url_show")@ResponseBodypublic String gotoPreAuthUrlShow(String key) {String hrefUrl="<a href='goto_auth_url?key="+key+"'>go</a>";return hrefUrl;}@GetMapping("/auth/goto_auth_url")public void gotoPreAuthUrl(HttpServletRequest request, HttpServletResponse response) {String key = request.getParameter("key");ServletUtil.setKey(key);String host = request.getHeader("host");String url = "https://" + host + "/wechatOpen/open/api/auth/jump?key=" + key;try {url = wxOpenService.getWxOpenComponentService().getPreAuthUrl(url);// 添加来源,解决302跳转来源丢失的问题response.addHeader("Referer", "https://" + host);response.sendRedirect(url);} catch (WxErrorException | IOException e) {logger.error("gotoPreAuthUrl", e);throw new RuntimeException(e);}}@GetMapping("/auth/jump")@ResponseBodypublic WxOpenQueryAuthResult jump(String key, @RequestParam("auth_code") String authorizationCode) {try {ServletUtil.setKey(key);WxOpenQueryAuthResult queryAuthResult = wxOpenService.getWxOpenComponentService().getQueryAuth(authorizationCode);logger.info("getQueryAuth", queryAuthResult);//存储授权appId,和authorCodevalOps.set("wxOpen:" + queryAuthResult.getAuthorizationInfo().getAuthorizerAppid(), authorizationCode);wxOpenService.updateAuthAccount(key,authorizationCode);return queryAuthResult;} catch (WxErrorException e) {logger.error("gotoPreAuthUrl", e);throw new RuntimeException(e);}}@GetMapping("/get_authorizer_info")@ResponseBodypublic WxOpenAuthorizerInfoResult getAuthorizerInfo(@RequestParam String appId) {try {return wxOpenService.getWxOpenComponentService().getAuthorizerInfo(appId);} catch (WxErrorException e) {logger.error("getAuthorizerInfo", e);throw new RuntimeException(e);}}
}
  •  这个用到的工具类
public class ServletUtil {private static final ThreadLocal<String> tl = new ThreadLocal<String>();public static String getKey() {//	ServletRequestAttributes	attributes=(ServletRequestAttributes)  RequestContextHolder.getRequestAttributes();//	return (String) attributes.getAttribute("key", RequestAttributes.SCOPE_REQUEST);//attributes.getRequest().getAttribute("key").toString();return tl.get();}public static void setKey(String key) {//	ServletRequestAttributes	attributes=(ServletRequestAttributes)  RequestContextHolder.getRequestAttributes();//	attributes.setAttribute("key",key, RequestAttributes.SCOPE_REQUEST);//	//attributes.getRequest().setAttribute("key",key);tl.set(key);}

 授权中获取ticket通过上面的receiveTicket这个方法

  • component_verify_ticket 的有效时间为12小时,比 component_access_token 更长,建议保存最近可用的component_verify_ticket,在 component_access_token 过期之前都可以直接使用该 component_verify_ticket 进行更新,避免出现因为 component_verify_ticket 接收失败而无法更新 component_access_token 的情况。其中component_access_token获取发送消息的token时需要用到,由于这个wx-java-open没有实现发消息功能,需要集成weixin-java-mp通用发消息功能。
  • weixin-java-mp依赖,通过这个就可以使用微信的通用发送消息接口,这里的access_token需要使用授权的auth_access_token来发送消息。

<dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>3.3.0</version>
</dependency>

微信公众平台接口

客服账号管理 | 微信开放文档 

 

authorizer_access_token获取方式 ,这个比较复杂,需要五步,其中component_access_token,authorizer_access_token有效期都有两小时。

Token生成说明 | 微信开放文档

其中authcode在授权后会拿到,需要保存下来。

 

ps:下面继续讲解下一步代码 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/438017.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VUE3动漫影视视频网站模板源码

文章目录 1.视频设计来源1.1 主界面1.2 动漫、电视剧、电影视频界面1.3 播放视频界面1.4 娱乐前线新闻界面1.5 关于我们界面 2.效果和源码2.1 动态效果2.2 源码结构 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/deta…

GBASE南大通用分享-ConnectionTimeout 属性

GBASE南大通用分享 获取或设置连接超时时间&#xff0c;值为‚0‛时没有限制。  语法 [Visual Basic] Public Overrides ReadOnly Property ConnectionTimeout As Integer Get [C#] public override int ConnectionTimeout { get; }  实现 IDbConnection.Connecti…

【文本到上下文 #7】探索 NLP 中的 Seq2Seq、编码器-解码器和注意力机制

一、说明 今天&#xff0c;我们将探讨序列到序列 &#xff08;seq2seq&#xff09; 模型的复杂工作原理&#xff0c;特别关注编码器-解码器架构和注意力机制。这些概念是各种 NLP 应用的基础&#xff0c;从机器翻译到问答系统。 这是可以期待的&#xff1a; Seq2Seq模型中的编码…

Android Automotive:在路上释放 Android 操作系统的力量

Android Automotive&#xff1a;在路上释放 Android 操作系统的力量 Android 在汽车行业的历程车载信息娱乐系统 (IVI) 的演变汽车中的 Android&#xff1a;演变和进步Android 汽车操作系统的崛起Polestar 2&#xff1a;开创 Android 汽车体验Android 开源项目 (AOSP) 及其他项…

ATAC-seq发篇测序文章就结束了吗?看如何利用ATAC-seq数据为后续关键基因的转录调控研究提供重要依据

染色质可及性&#xff08;Chromatin Accessibility&#xff09;是染色质的一种特性&#xff0c;为转录因子结合靶基因提供了空间。转座酶可及染色质测序分析&#xff08;ATAC-seq&#xff09;是常见的研究染色质可及性的方法&#xff0c;ATAC-seq联合RNA-seq是一种新的研究思路…

【前端开发】CSS中的:hover伪类选择器 你真的搞懂怎么去使用它吗?

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起学习和进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&a…

某大厂关于Linux系统相关面试题

一、Linux系统和Shell 1、写一个sed命令&#xff0c;修改/tmp/input.txt文件的内容&#xff0c;要求&#xff1a;(1) 删除所有空行&#xff1b;(2) 在非空行前面加一个"AAA"&#xff0c;在行尾加一个"BBB"&#xff0c;即将内容为11111的一行改为&#xff1…

【Linux】第三十八站:信号处理

文章目录 一、信号处理二、再谈进程地址空间三、内核如何实现信号的捕捉四、sigaction 一、信号处理 我们知道&#xff0c;信号保存以后&#xff0c;会在合适的时候进行处理这个信号。 那么信号是如何被处理的&#xff1f;什么时候进行处理呢&#xff1f; 当我们的进程从内核…

如何在Microsoft 365中直接启用 Loop服务

Microsoft Loop是一种变革性共同创建体验&#xff0c;可将工具和设备上的团队、内容和任务汇集在一起&#xff0c;使团队能够共同思考、规划和创建内容。 在之前分享过的文章中已经介绍了如何在Microsoft Teams、Outlook和Word中使用Loop服务&#xff0c;今天继续介绍如何在Mi…

微信小程序上传时报错message:Error: 系统错误,错误码:80051,source size 2148KB exceed max limit 2MB

问题&#xff1a; 微信小程序上传时错误码&#xff1a;80051,source size 2248KB exceed max limit 2MB 问题原因&#xff1a; 由于代码中的静态资源 图片大小超了200k以及主包的体积超出1.5M 解决办法 分包 tabBar 是主包的&#xff0c;不需要分包处理&#xff0c;以下是分…

http和https的区别是什么?https有什么优缺点?

HTTP&#xff08;Hypertext Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一个简单的请求-响应协议&#xff0c;它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。这个简单模型是早期Web成功的有功之臣&#xff0c;因为它…

在Java中,如何实现对象的拷贝?

开发中可以使用第三方库如Apache Commons Lang的SerializationUtils类或Google的Guava库来实现对象的深拷贝。这些库提供了更加灵活和方便的深拷贝实现方式&#xff0c;同时也提供了更多的自定义选项和错误处理机制。 在Java中&#xff0c;对象的拷贝可以分为浅拷贝&#xff0…