官方文档

最好先熟悉以上文档

正文:

1: 授权流程

1、推送component_verify_ticket协议

在第三方平台创建审核通过后,微信服务器会向其“授权事件接收URL”每隔10分钟定时推送component_verify_ticket。第三方平台方在收到ticket推送后也需进行解密(详细请见【消息加解密】),接收到后必须直接返回字符串success。

   /*** 接收ticket 微信每10分钟推送一次*/@PostMapping("ticket")public String ticket(HttpServletRequest request) throws Exception {log.info("接收ticket==================》开始");String msgSignature = request.getParameter("msg_signature");String timeStamp = request.getParameter("timestamp");String nonce = request.getParameter("nonce");log.info("开始接受postdata---" + request.getInputStream());BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));StringBuffer sb = new StringBuffer();String line = null;while ((line = br.readLine()) != null) {sb = sb.append(line);}String postData = sb.toString();log.info(msgSignature + "==============》" + timeStamp + "==============》" + nonce + "==============》" + postData);WXBizMsgCrypt pc = new WXBizMsgCrypt(WeiXinConstant.TOKEN, WeiXinConstant.ENCODING_AESKEY, WeiXinConstant.THREE_APP_ID);String result = pc.decryptMsg(msgSignature, timeStamp, nonce, postData);//appId 第三方平台APPid;// InfoType component_verify_ticket;// ComponentVerifyTicket Ticket内容log.info(result + ".................");//保存最新的ticket为10分钟,微信每十分钟会掉一次该接口Map map = XmlToMapUtil.toMap(result);if (CollectionUtils.isEmpty(map)) {log.info("map===================>null【{}】", JSON.toJSONString(map));return "";}log.info(map.get("ComponentVerifyTicket").toString() + "》=============================");redisUtil.set("ticket", map.get("ComponentVerifyTicket").toString(), 10 * 60 * 1000);return "success";}

2、获取第三方平台component_access_token

注意:第三方平台component_access_token是第三方平台的下文中接口的调用凭据,也叫做令牌(component_access_token)。每个令牌是存在有效期(2小时)的,且令牌的调用不是无限制的,请第三方平台做好令牌的管理,在令牌快过期时(比如1小时50分)再进行刷新。

    @GetMapping("getComponentAccessToken")@ApiOperation("获取第三方平台component_access_token")public ApiResponse getComponentAccessToken() {//测试用String componentVverifyTicket = String.valueOf(redisUtil.get("ticket"));log.info("获取第三方平台component_access_token==========》componentVverifyTicket【{}】", componentVverifyTicket);Map parampMap = new HashMap();//component_appid  第三方平台appidparampMap.put("component_appid", WeiXinConstant.THREE_APP_ID);//component_appsecret 第三方平台appsecretparampMap.put("component_appsecret", WeiXinConstant.THREE_APP_SCREPT);//微信后台推送的ticket,此ticket会定时推送,即 步骤1里的值parampMap.put("component_verify_ticket", componentVverifyTicket);String apiComponentToken = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";ResponseEntity<String> entity = restTemplate.postForEntity(apiComponentToken, parampMap, String.class);if (entity.getStatusCode().equals(HttpStatus.OK)) {entity.getBody();log.info("获取第三方平台component_access_token==========》【{}】", entity.getBody());//保存最新的redisUtil.set("component_access_token", JSON.parseObject(entity.getBody()).getString("component_access_token"));} else {log.error("获取第三方平台component_access_token==========》失败!");}return ResponseUtil.success(entity.getBody());}

正确返回结果:

{"component_access_token":"61W3mEpU66027wgNZ_MhGHNQDHnFATkDa9-2llqrMBjUwxRSNPbVsMmyD-yq8wZETSoE5NQgecigDrSHkPtIYA", "expires_in":7200}

有效期为7200s 如需长期使用,缓存起来,在未到期之前提前刷新该值

3,获取预授权码pre_auth_code

    @GetMapping("getPreAuthCode")@ApiOperation("通过ComponentAccessToken获取第三方预授权码")public ApiResponse getPreAuthCode() {//测试String componentAccessToken = String.valueOf(redisUtil.get("component_access_token"));log.error("获取预授权码pre_auth_code==========》开始!");Map parampMap = new HashMap();//WeiXinConstant.THREE_APP_ID 第三方平台的APPIDparampMap.put("component_appid", WeiXinConstant.THREE_APP_ID);StringBuffer stf = new StringBuffer("https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode");//componentAccessToken 步骤2的值stf.append("?component_access_token=").append(componentAccessToken);ResponseEntity<String> entity = restTemplate.postForEntity(stf.toString(), parampMap, String.class);if (entity.getStatusCode().equals(HttpStatus.OK)) {entity.getBody();log.info("获取预授权码pre_auth_code==========【{}】", entity.getBody());//每次存入最新的redisUtil.set("pre_auth_code", JSON.parseObject(entity.getBody()).getString("pre_auth_code"), 600);} else {log.error("获取预授权码pre_auth_code==========》失败!");}return ResponseUtil.success(entity.getBody());}

正确返回:

{"pre_auth_code":"Cx_Dk6qiBE0Dmx4EmlT3oRfArPvwSQ-oa3NL_fwHM7VI08r52wazoZX2Rhpz1dEw","expires_in":600}

4,使用授权码换取公众号或小程序的接口调用凭据和授权信息

注意注意注意:此步骤很重要,4.1 和4.2 选一种参考即可,推荐4.2

网页授权发起的请求需要和在三方平台上的填写的域名一样才可以,否则会报域名发起错误

4.1.授权注册页面扫码授权

    @GetMapping("getAuthorizationCodeByPC")@ApiOperation("获取授权页面")public ApiResponse getAuthorizationCodeByPC() {log.error(" 获取授权页面=========》开始!");String preauthcode = String.valueOf(redisUtil.get("pre_auth_code"));StringBuffer stf = new StringBuffer("https://mp.weixin.qq.com/cgi-bin/componentloginpage?");stf.append("component_appid=").append(WeiXinConstant.THREE_APP_ID);stf.append("&pre_auth_code=").append(preauthcode);stf.append("&redirect_uri=").append("http://zhaojunjie.nat300.top/receive/authorizationCode");log.info("请求页面【{}】", stf.toString());ResponseEntity<String> entity = restTemplate.getForEntity(stf.toString(), String.class);if (entity.getStatusCode().equals(HttpStatus.OK)) {log.info(" 获取授权页面=========》SUCCESS");} else {log.error(" 获取授权页面=========》失败!");}return ResponseUtil.success(entity.getBody());}

4.2.点击移动端链接快速授权

    @GetMapping("getAuthorizationCodeByAp")@ApiOperation("获取授权链接移动端")public ApiResponse getAuthorizationCodeByAp() {log.error("授权链接移动端=========》开始!");String preauthcode = String.valueOf(redisUtil.get("pre_auth_code"));StringBuffer stf = new StringBuffer("https://mp.weixin.qq.com/safe/bindcomponent?action=bindcomponent&auth_type=3&no_scan=1");stf.append("&component_appid=").append(WeiXinConstant.THREE_APP_ID);stf.append("&pre_auth_code=").append(preauthcode);stf.append("&redirect_uri=").append("https://jikezhan.com/manager/receive/authorizationCode");stf.append("&auth_type=").append("2").append("#wechat_redirect");log.info("授权链接移动端【{}】", stf.toString());ResponseEntity<String> entity = restTemplate.getForEntity(stf.toString(), String.class);if (entity.getStatusCode().equals(HttpStatus.OK)) {log.info(" 授权链接移动端=========》SUCCESS");} else {log.error(" 授权链接移动端=========》失败!");}return ResponseUtil.success(entity.getBody());}

两种授权方式选择一种测试就行,第一种生成的网页要在设置的域名下认证。所以推荐第二种,移动端授权生成的链接直接发送给授权方授权即可,授权成功后会收到微信的通知,回调接口如下:

   /*** 用户扫码授权后的回调* 授权成功后会返回授权code*/@GetMapping("authorizationCode")public String authorizationCode(HttpServletRequest request) {log.info("预授权码换取授权码回调接口=========》开始【{}】", JSON.toJSONString(request.getParameterMap()));//{"auth_code":["queryauthcode@@@jD3ANR367yXFce3z-     8ALAh_lQ4Tmr_sPyLRf20SKVwmv1UpnVVqp22FEWLv5_mSu1BKEAX3zKFrB9yW3P8fLew"],"expires_in":["3600"]}//授权code,会在授权成功时返回给第三方平台log.info("授权码======================》【{}】", request.getParameterMap().get("auth_code"));String[] authCode = request.getParameterMap().get("auth_code");redisUtil.set("authorizationCode", StringUtils.join(authCode), 7200);return "success";}

同样是有时效性的

4.3
该API用于使用授权码换取授权公众号或小程序的授权信息,并换取authorizer_access_token和authorizer_refresh_token。 授权码的获取,需要在用户在第三方平台授权页中完成授权流程后,在回调URI中通过URL参数提供给第三方平台方。请注意,由于现在公众号或小程序可以自定义选择部分权限授权给第三方平台,因此第三方平台开发者需要通过该接口来获取公众号或小程序具体授权了哪些权限,而不是简单地认为自己声明的权限就是公众号或小程序授权的权限。

    @GetMapping("apiQueryAuth")public ApiResponse apiQueryAuth() {log.info("使用授权码换取公众号或小程序的接口调用凭据和授权信息=========》开始");String authorizationCode = String.valueOf(redisUtil.get("authorizationCode"));log.info("authorizationCode========================》【{}】", authorizationCode);String componentAccessToken = String.valueOf(redisUtil.get("component_access_token"));log.info("componentAccessToken========================》【{}】", componentAccessToken);Map parampMap = new HashMap();parampMap.put("component_appid", WeiXinConstant.THREE_APP_ID);//authorization_code 即上述4.1 或4.2用户授权后微信推送给我们的parampMap.put("authorization_code", authorizationCode);StringBuffer stf = new StringBuffer("https://api.weixin.qq.com/cgi-bin/component/api_query_auth");stf.append("?component_access_token=").append(componentAccessToken);log.info("链接【{}】", stf.toString());ResponseEntity<String> entity = restTemplate.postForEntity(stf.toString(), parampMap, String.class);if (entity.getStatusCode().equals(HttpStatus.OK)) {JSONObject result = JSON.parseObject(entity.getBody());JSONObject authorizationInfo = (JSONObject) result.get("authorization_info");//授权的APPIDString authorizerAppid = authorizationInfo.getString("authorizer_appid");redisUtil.set("authorizer_appid", authorizerAppid);//authorizer_access_tokenString authorizerAccessToken = authorizationInfo.getString("authorizer_access_token");redisUtil.set("authorizer_access_token", authorizerAccessToken, 7200);//刷新tokenString authorizerRefreshToken = authorizationInfo.getString("authorizer_refresh_token");redisUtil.set("authorizer_refresh_token", authorizerRefreshToken);log.info("使用授权码换取公众号或小程序的接口调用凭据和授权信息=========》【{}】", entity.getBody());} else {log.error("使用授权码换取公众号或小程序的接口调用凭据和授权信息=========》失败!");}return ResponseUtil.success(entity.getBody());}

返回结果示例

{"authorization_info": {"authorizer_appid": "wxf8b4f85f3a794e77",
"authorizer_access_token": "QXjUqNqfYVH0yBE1iI_7vuN_9gQbpjfK7hYwJ3P7xOa88a89-Aga5x1NMYJyB8G2yKt1KCl0nPC3W9GJzw0Zzq_dBxc8pxIGUNi_bFes0qM",
"expires_in": 7200,
"authorizer_refresh_token": "dTo-YCXPL4llX-u1W1pPpnp8Hgm4wpJtlR6iV0doKdY",
"func_info": [
{"funcscope_category": {"id": 1
}
},
{"funcscope_category": {"id": 2
}
},
{"funcscope_category": {"id": 3
}
}
]
}}

返回参数:
authorization_info 授权信息
authorizer_appid 授权方appid
authorizer_access_token 授权方接口调用凭据(在授权的公众号或小程序具备API权限时,才有此返回值),也简称为令牌
expires_in 有效期(在授权的公众号或小程序具备API权限时,才有此返回值)
authorizer_refresh_token
接口调用凭据刷新令牌(在授权的公众号具备API权限时,才有此返回值),刷新令牌主要用于第三方平台获取和刷新已授权用户的access_token,只会在授权时刻提供,请妥善保存。 一旦丢失,只能让用户重新授权,才能再次拿到新的刷新令牌


authorizer_access_token 有时效性,在后续的接口会经常用到,所以尽量在到期之前提前使用 authorizer_refresh_token
刷新 authorizer_access_token代码如下:

    @GetMapping("authorizerRefreshToken")@ApiOperation("获取(刷新)授权公众号或小程序的接口调用凭据(令牌)")public ApiResponse authorizerRefreshToken() {String componentAccessToken = String.valueOf(redisUtil.get("component_access_token"));StringBuffer stf = new StringBuffer("https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=");stf.append(componentAccessToken);Map<String, String> parmMap = new HashMap();String authorizerRefreshToken = redisUtil.get("authorizer_refresh_token") == null ? "" : String.valueOf(redisUtil.get("authorizer_refresh_token"));parmMap.put("component_appid", WeiXinConstant.THREE_APP_ID);parmMap.put("authorizer_appid", String.valueOf(redisUtil.get("authorizer_appid")));parmMap.put("authorizer_refresh_token", authorizerRefreshToken);ResponseEntity<String> entity = restTemplate.postForEntity(stf.toString(), parmMap, String.class);if (entity.getStatusCode().equals(HttpStatus.OK)) {JSONObject result = JSONObject.parseObject(entity.getBody());String authorizerAccessToken = result.getString("authorizer_access_token");redisUtil.set("authorizer_access_token", authorizerAccessToken, 7200);String newAuthorizerRefreshToken = result.getString("authorizer_refresh_token");redisUtil.set("authorizer_refresh_token", newAuthorizerRefreshToken);log.info("获取(刷新)授权公众号或小程序的接口调用凭据(令牌)=========》【{}】", entity.getBody());} else {log.error("获取(刷新)授权公众号或小程序的接口调用凭据(令牌)=========》失败!");}return ResponseUtil.success(entity.getBody());}

本人QQ:571726193

群(新 人少) :1030289715

欢迎来交流,什么问题也欢迎指出。

NO.2 微信第三方平台(小程序)授权流程技术说明相关推荐

  1. 微信第三方平台小程序平台设计

    今天是2023年1月15日,距离2023春节倒计时7天.在此,我分享一下个人对于微信第三方平台小程序的理解以及搭建一个微信小程序及云端服务的一些个人经验,作为交流. 首先,一个第三方平台小程序要定位是 ...

  2. 微信第三方平台公众号授权流程1—第三方平台概述概述

    一.概述 公众平台第三方平台是为了让公众号或小程序运营者,在面向垂直行业需求时,可以一键授权给第三方平台(并且可以同时授权给多家第三方),通过第三方平台来完成业务,开放给所有通过开发者资质认证后的开发 ...

  3. 微信,支付宝支付,微信公众号小程序授权等

    微信,支付宝支付,微信公众号小程序授权等 前言 微信支付 微信授权 maven依赖(更新) 前言 最近在公司也做了很多移动端项目,如今微信公众号,小程序又特别火爆,免不了要接触支付,授权这类的业务需求 ...

  4. 从微信公众平台·小程序内测邀请函看应用号动向

    最近,网上流传一张疑似张小龙朋友圈的照片,上面写着:"什么是小程序:小程序是一种不需要下载安装即可使用的应用,它实现了应用"触手可及"的梦想,用户扫一扫或者搜一下即可打开 ...

  5. 微信公众平台小程序(应用号)开始内测了

    在今年1月的微信公开课Pro版现场,微信团队曾经提到,微信将在订阅号和服务号的基础上,推出应用号. 微信小程序正式上线 [爆]小程序内可直接打开网页了! 2017年3月27日更新:微信小程序新增六大能 ...

  6. 微信公众平台、微信公众平台.小程序、微信.开放平台三者关系及unionid

    以下内容,仅限于根据自己开发以及阅读微信文档总结,错误之处敬请指出,共同进步! 一.微信公众平台.微信公众平台.小程序.微信.开放平台登录地址 项目 微信公众平台 微信公众平台.小程序 微信.开放平台 ...

  7. 关于微信小程序上传,在微信公众平台|小程序中找不到上传的代码

    2019/05/16 小程序小白入门 最开始的时候,我不知道该如何上传自己的代码.打开微信开发平台,找到"工具"选项,再点击"上传"就好了 ①找到"工 ...

  8. 微信开放平台:小程序代码模板库管理 小程序授权 版本发布,版本回退 java代码实现

    一.业务场景: 小程序运营者,可以一键授权给第三方平台,通过第三方平台来完成代公众号和代小程序等业务,本文主要介绍代小程序业务实现步骤. 二.代开发的具体流程: 第三方平台帮已授权的小程序进行代码管理 ...

  9. 微信公众平台-小程序开发工具源码

    饮水思源,手有余香,今天微信发布小程序开发,无异于对开发者是一场不大不小的地震,大家褒贬不一,偶然  从  别处大神得到今天微信刚推出的小程序开发,旨在学习技术交流,一起共同进步 下面分享开发工具: ...

最新文章

  1. web service 项目 和 普通 web项目 的 区别
  2. 使用git时ssh提示“Load key /home/devid/.ssh/id_rsa: bad permissions”的解决办法
  3. [html] 你知道什么是反向链接吗?它有什么应用场景呢?
  4. 天池-街景字符编码识别5-模型训练与验证
  5. bzoj 4318 OSU!
  6. .net下导致Session失效的一种情况:js教本中使用window.open和window.showModalDialog时需要注意...
  7. jquery动态生成的元素添加事件的方法
  8. mysql 启动必须加-h_Windows 安装 nginx,MySQL 等软件并加入系统服务启动详细
  9. Atitit spirngboot 访问 html文件总结 自设计web服务器原理与实现 Url路由压力,读取url,获得项目更路径绝对路径,拼接为文件路径。读取文建内容输出即可 目录路径 u
  10. soui 设置边框_UI神器-SOUI
  11. PE下安装win XP 64位实战
  12. 为什么都说阿里P7的晋升是道坎?
  13. python 时间曲线相似度计算_时间序列相似性度量综述
  14. python求奇偶数和_用Python返回偶数和奇数
  15. Admin-UI分布式微服务监控中心
  16. LaTex关于数学公式的使用(5)--- 积分
  17. 英读廊——尬跑一英里
  18. Cricuit Switched Fallback (CSFB) : CDMA2000 1XRTT
  19. [Unity3D]Unity3D游戏开发之Xml解析实现NPC对话系统
  20. 总结开发者在合作过程中的典型交流方式

热门文章

  1. WF100DPZ 1BG S6 DT数字压力传感器
  2. linux服务器被挖矿的解决办法
  3. 计算机网络-HTTP协议
  4. 【matlab图像处理】matlab数据结构(1)
  5. 名帖291 董其昌 行书《乐志论》
  6. IntelliJ IDEA 快捷键及模板Templates设置
  7. 新意互动董事长兼CEO曲伟海出席2021中国企业家博鳌论坛
  8. CAD点位坐标提取的方法
  9. 省心又省力的华为云等保安全服务----助力企业等保快速通过
  10. OCAD应用:双高斯照相物镜系统结构优化设计