【微信】公众号授权绑定登录流程详解

在做微信公众号开发时,经常需要对公众号上面的菜单做授权登录,如果是首次登录还需要做微信openId和系统账号的绑定操作。

这里做如下假设:

  • 系统前端地址:http://www.test.com
  • 系统接口地址:http://api.test.com
  • 需要打开的页面地址:http://www.test.com/home/index

一、微信公众号配置

1、公众号注册以及实名认证
2、在“基本配置”中启用开发者密码(记得复制AppID、AppSecret),并设置IP白名单
3、在“公众号设置-功能设置”中,配置“业务域名、JS接口安全域名、网页授权域名”

注意:上面几个操起需要将微信授权文件(MP_verify_xxxxx.txt)下载存放在服务器上,需要让http://www.test.com/MP_verify_xxxxx.txt可以访问。
假设把文件放在目录/usr/share/nginx/file中,然后配置nginx,让该链接可以访问,例如:

# 微信授权文件通用匹配规则
location ~(MP_verify_)*\.(txt)$ {root   /usr/share/nginx/file;
}

在这里插入图片描述

4、在“开发者工具-web开发者工具”中,绑定开发者微信号,便于在微信开发者工具中调试

在这里插入图片描述

二、服务端开发

1、引入第三方微信公众号sdk

这里推荐开源项目WxJava

在pom.xml中引入第三方jar包

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

2、配置微信公众号服务

1)将复制下来的AppID、AppSecret配置在application.yml

wx:appId: wxd8e8db2818fxxxxxappSecret: 4a22ab04b25eb155bd8b6a540cxxxxx# 前端账号绑定页面urlbindUrl: http://www.test.com/wxBind# 后端微信授权回调urlcallback: http://api.test.com/wx/auth/callback

2)新建配置属性类WxProperties.java

@ConfigurationProperties(prefix = "wx")
@Data
public class WxProperties {private String appId;private String appSecret;private String bindUrl;private String callback;
}

3)新增配置类WxConfig.java

@Configuration
@EnableConfigurationProperties(WxProperties.class)
public class WxConfig {private WxProperties wxProperties;public WxConfig(WxProperties wxProperties) {this.wxProperties = wxProperties;}@Beanpublic WxMpService wxMpService(){WxMpService wxMpService = new WxMpServiceImpl();WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();configStorage.setAppId(wxProperties.getAppId());configStorage.setSecret(wxProperties.getAppSecret());wxMpService.setWxMpConfigStorage(configStorage);return wxMpService;}
}

3、编写回调及绑定接口

1)新建微信授权回调接口Controller,编写授权回调接口

如果用户还未绑定,需要把openId传给前端,前端在绑定登录时,一起作为参数传回到后端的绑定接口

@Slf4j
@Controller
@RequestMapping("/wx/auth")
public class WxAuthController {@Resourceprivate WxMpService wxMpService;@Resourceprivate WxProperties wxProperties;@RequestMapping("/callback")public String callback(Model model, String state, String code) throws WxErrorException {log.info("wx callback, code:{},state:{}", code, state);WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code);String openId = accessToken.getOpenId();// 根据openId查找账号,如果不存在则新增绑定String sysUserId = sysUserService.loadByWxOpenId(openId);if (StringUtils.isNotBlank(sysUserId)) {// 执行登录LoginUser loginUser = sysUserService.getUserById(sysUserId);// 跳转到前端页面地址if (StringUtils.isNotBlank(state) && StringUtils.startsWith(state, "http")) {// 生成登录Token,返回给前端// 示例代码是通过Jwt生成Token,然后存储在Redis中String token = saveToken(loginUser);model.addAttribute("token", token);log.info("公众号自动登录,userId:{},wxOpenId:{}", loginUser.getId(), openId);return "redirect:" + state + "?token=" + token;}}log.info("公众号未绑定,wxOpenId:{}", openId);// 找不到已绑定记录,跳转到绑定页面,执行绑定return "redirect:" + wxProperties.getBindUrl() + "?wxOpenId=" + openId + "&state=" + state;}// ... 暂时忽略其他方法 ....//
}

2)编写账号绑定接口

先校验账号密码,然后把微信openId和用户userId绑定,下次登录时候就可以根据openId查询到userId

@Data
public class WxBindVo {@ApiModelProperty(value = "微信openId")private String wxOpenId;@ApiModelProperty(value = "账号")private String username;@ApiModelProperty(value = "密码")private String password;
}@RequestMapping("/bind")
@ResponseBody
public Result<JSONObject> bind(@RequestBody WxBindVo wxBindVo) throws WxErrorException {log.info("wx bind, {}", wxBindVo);Result<JSONObject> result = new Result<>();JSONObject obj = new JSONObject();// 执行绑定,然后自动登录,等完成后跳转到原来的页面LoginUser loginUser = sysUserService.checkUser(wxBindVo.getUsername(), wxBindVo.getPassword());if (loginUser != null) {//绑定微信OpenIdsysUserService.saveWxAccount(loginUser.getId(), wxBindVo.getWxOpenId());//用户登录信息obj.put("userInfo", loginUser);obj.put("token", saveToken(loginUser));result.setResult(obj);result.setSuccess(true);result.setCode(200);log.info("微信公众号绑定后自动登录,userId:{}, wxOpenId:{}", loginUser.getId(), wxBindVo.getWxOpenId());return result;}result.setResult(obj);result.setSuccess(false);result.setMessage("公众号登录失败,请联系管理员");return result;
}

3)编写微信公众号授权菜单入口

有了这个入口方法,只要将微信公众号菜单统一配置到这就可以,将需要打开的页面url传给state参数。

例如:http://api.test.com/wx/auth/index?state=http://www.test.com/home/index

/*** 微信公众号授权菜单入口* @param state 授权登录跳转的页面url*/
@RequestMapping("/index")
public String index(String state) {String url = wxProperties.getCallback();String authorizationUrl = wxMpService.getOAuth2Service().buildAuthorizationUrl(url, WxConsts.OAuth2Scope.SNSAPI_BASE, URIUtil.encodeURIComponent(state));log.info("authorizationUrl = {}", authorizationUrl);return "redirect:" + authorizationUrl;
}

三、前端页面开发

当然,还有前端绑定页面开发,这里主要讲解流程,前端代码省略

四、在公众号中配置菜单

打开公众号“内容于互动-自定义菜单”,添加添加菜单,输入菜单名单和跳转网页链接

这里网页链接假设是:http://api.test.com/wx/auth/index?state=http://www.test.com/home/index

在这里插入图片描述

四、相关流程图

1、公众号授权登录时序图

在这里插入图片描述

2、公众号授权登录流程图

在这里插入图片描述

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

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

相关文章

Activity启动过程

首语 Activity作为Android四大组件中使用最频繁的组件&#xff0c;也是和用户交互最多的组件&#xff0c;可见它在Android技术体系的核心地位&#xff0c;了解Activity的启动过程可以帮助我们更好的了解Android系统和使用Activity。 文章目录 首语Activity启动过程根Activity…

加强->servlet->tomcat

0什么是servlet jsp也是servlet 细细体会 Servlet 是 JavaEE 的规范之一&#xff0c;通俗的来说就是 Java 接口&#xff0c;将来我们可以定义 Java 类来实现这个接口&#xff0c;并由 Web 服务器运行 Servlet &#xff0c;所以 TomCat 又被称作 Servlet 容器。 Servlet 提供了…

打造完备数据生态,「开放互信、合作共赢」: 拓数派亮相2023龙蜥操作系统大会

拓数派始终持「开放互信&#xff0c;合作共赢」的理念&#xff0c;通过积极建立合作伙伴生态网络、构建生态工具、打造活跃的技术和用户社区等方式&#xff0c;构筑更加完善的数据生态体系&#xff0c;为用户带来更加便捷的使用体验。2023年12月17-18日&#xff0c;由开放原子开…

如何实现无公网ip环境访问vscode远程开发【内网穿透】

文章目录 前言1、安装 OpenSSH2、vscode 配置 ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu 安装 cpolar 内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定 TCP 端口地址5.1 保留一个固定 TCP 端口地址5.2 配置固定 TCP 端口地址5.3 测试固定公网地址远…

vue exceljs json数据转excel

json数据转excel 有时候我们会遇到这样一个需求&#xff0c;就是将数据转成excel下载&#xff0c;这一般都是由后端来处理&#xff0c;使用插件poi轻松搞定。如果只有少量数据&#xff0c;那么能不能避免调用后端接口&#xff0c;前端直接处理呢&#xff1f; 答案是&#xff…

使用Vue3开发学生管理系统模板5 学生家长信息的实现

字段设计 IDname&#xff1a;姓名&#xff0c;字符串&#xff0c;最长36个字符gender&#xff1a;性别&#xff0c;字符串&#xff0c;最长6个字符串age&#xff1a;年龄&#xff0c;数字类型phone&#xff1a;电话&#xff0c;字符串&#xff0c;最长20个字符student_id&…

无需手动搜索!轻松创建IntelliJ IDEA快捷方式的Linux教程

轻松创建IntelliJ IDEA快捷方式的Linux教程 一、IntelliJ IDEA简介二、在Linux系统中创建快捷方式的好处三、命令行创建IntelliJ IDEA快捷方式四、图形界面创建IntelliJ IDEA快捷方式五、常见问题总结 一、IntelliJ IDEA简介 IntelliJ IDEA是一个由JetBrains搞的IDE&#xff0…

搭建FTP服务器详细介绍

一.FTP简介 &#xff11;.&#xff11;什么是FTP &#xff11;.&#xff12;FTP服务器介绍 &#xff11;.&#xff13;FTP服务器优缺点 二.FTP服务器的搭建与配置 2.1 开启防火墙 2.2创建组 2.3创建用户 2.4安装FTP服务器 2.5配置FTP服务器 &#xff12;.&#xff…

麒麟KYLINOS _ 传书 _ 如何传输文件?

原文链接&#xff1a;麒麟KYLINOS | 传书 | 如何传输文件&#xff1f; hello&#xff0c;大家好啊&#xff01;今天我要给大家介绍的是在麒麟KYLINOS操作系统上使用自带的文件传输软件——传书。在日常工作和生活中&#xff0c;我们经常需要在不同设备之间传输文件和信息。传书…

论文阅读《Restormer: Efficient Transformer for High-Resolution Image Restoration》

论文地址:https://openaccess.thecvf.com/content/CVPR2022/html/Zamir_Restormer_Efficient_Transformer_for_High-Resolution_Image_Restoration_CVPR_2022_paper.html 源码地址:https://github.com/swz30/Restormer 概述 图像恢复任务旨在从受到各种扰动(噪声、模糊、雨滴…

账号租号平台PHP源码,支持单独租用或合租使用

源码简介 租号平台源码&#xff0c;采用常见的租号模式。 平台的主要功能如下&#xff1a; 支持单独租用或采用合租模式&#xff1b; 采用易支付通用接口进行支付&#xff1b; 添加邀请返利功能&#xff0c;以便站长更好地推广&#xff1b; 提供用户提现功能&#xff1b;…

超强整理,Web自动化测试-验证码/cookie机制(详全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、后台登录案例 …

C#使用SyntaxTree获取.cs文件中的属性名和注释

有时候&#xff0c;我们可能需要获取.cs文件中的属性和对应的注释来生成一些代码&#xff0c;比如SQL查询什么的。 但使用正则匹配有时候会不准确。搜索了下&#xff0c;发现微软提供了代码解析的API。 具体如下两个方法&#xff1a; /// <summary> /// 获取所有属性和…

Springboot整合Elastic-job

一 概述 Elastic-Job 最开始只有一个 elastic-job-core 的项目&#xff0c;定位轻量级、无中心化&#xff0c;最核心的服务就是支持弹性扩容和数据分片&#xff01;从 2.X 版本以后&#xff0c;主要分为 Elastic-Job-Lite 和 Elastic-Job-Cloud 两个子项目。esjbo官网地址 Ela…

【五】【C语言\动态规划】删除并获得点数、粉刷房子、买卖股票的最佳时机含冷冻期,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…

Docker部署Plik临时文件上传系统并实现远程访问设备上传下载文件

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设备上传或者…

K8S中的job和CronJob

Job 介绍 Kubernetes jobs主要是针对短时和批量的工作负载。它是为了结束而运行的&#xff0c;而不是像deployment、replicasets、replication controllers和DaemonSets等其他对象那样持续运行。 示例 apiVersion: batch/v1 kind: Job metadata:name: pispec:template:spec:r…

Golang - 执行 shell 脚本,并实时按行打印 shell 脚本输出信息

原文链接&#xff1a;https://blog.csdn.net/flyfreelyit/article/details/103697013 测试代码地址&#xff1a;https://github.com/kirinlabs/execshell Golang 执行 shell 脚本&#xff0c;不接收返回值 // 返回一个 cmd 对象 cmd : exec.Command("sh", "-c…

【持续学习系列(四)】《Lifelong-RL》

一、论文信息 1 标题 Lifelong-RL: Lifelong Relaxation Labeling for Separating Entities and Aspects in Opinion Targets 2 作者 Lei Shu, Bing Liu, Hu Xu, and Annice Kim 3 研究机构 Department of Computer Science, University of Illinois at Chicago, USACent…

MySQL 和 MySQL2 的区别

MySQL是最流行的开源关系型数据库管理系统,拥有大量的使用者和广泛的应用场景。而MySQL2是MySQL官方团队推出的新一代MySQL驱动&#xff0c;用于取代老版的MySQL模块&#xff0c;提供更好的性能和更丰富的功能。 本文将介绍MySQL2相较于MySQL有哪些优势以及具体的技术区别。 …