微信公众号对接获取用户openid预约项目心路全历程

公众号对接获取openid全历程

    • 一、背景
    • 二、选型
    • 三、开始修改若依框架
    • 四、自己搭后端框架
    • 五、前端框架uni-app修改
    • 六、对接获取公众号登录用户openId
    • 七、总结

一、背景

老板接了朋友的一个公众号需求,要求做一个简单的疫苗预约系统。功能是获取当前登录用户,记录用户选择的疫苗,针次,时间,并且用户可以查看自己预约的记录。我刚接到这个需求感觉也简单,给的时间呢也只有一周,包括程序的开发,服务的部署,公众号相关信息的配置。虽然是个很小的功能,没想到期间碰到过很多坑,公众号也是我第一次全流程的做,记录一下这期间的坎坷。

二、选型

一般接到这种小功能的开发,我们一般会在开源框架市场找几个相似的项目然后修修改改,达到甲方想要的使用预期。前三天基本都是浪费在选型这一块了,本来也想着,选好开源项目,改起来也快,最后敲定选用若依uni-app这款,可没想到,最后改了半天,最后忍无可忍,自己手写了一套后端,前端代码,框架当然用的还是springboot+uni-app。。。

三、开始修改若依框架

若依这套框架也是典型的租户型框架,uniapp启动后是一个登录界面,而公众号要做默认登录,是不要这个登录界面的,那怎么跳过这个登录界面,直接登录进去呢,一开始想的是默认获取用户openid直接授权进去,这就要对应的修改后端生成token的方式,然后每一个页面访问的header还要携带这个token。

除此之外,登录进去后才展示的业务界面还需要画一下,那就先把页面画出来,一共做了四个页面,用户首页(展示预约疫苗入口和用户预约记录),用户信息维护(点击预约疫苗后先维护自己的信息,包括姓名,身份证号,手机号),预约界面(三个相互隐藏的栏位,疫苗栏位,针次栏位,时间栏位),疫苗说明界面。这里说一下微信公众号静默获取的信息只能获取到openId,unionid应该也可以获取,我没试过。获取openId的过程后面会说明。这里让用户自己维护手机号和身份证号是因为可能会给长辈预约疫苗。

页面画完之后,数据都是用的前端代码模拟的值,流程无碍之后,准备后端添加接口,业务表是甲方直接提供,使用的是sqlServer数据库,若依用的数据库版本是mysql,最后又找了一下,找到了若依sqlserver版本的后端框架,发现没法改,主要还是认证这一个部分,如果要改造认证这一部分,又要花费很多工作时间,改造过程中可能还会产生新的问题或者bug都是没法预估的,不是说若依不好用,只能说没必要用这种shiro认证框架,太冗余了。

四、自己搭后端框架

不需要认证,获取到当前登录用户的openID进行数据隔离和查询也可以保证数据的安全性。

  • 新建一个springboot项目

  • 删除多余的文件夹

  • 修改pom.xml的一些配置和添加我所需要的maven依赖,sqlSerer驱动,mybatisplus,springboot启动的依赖自带的,fastjson,druid数据池,多数据源,lombok,当然hutool也要

        <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- 阿里JSON解析器 --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.75</version></dependency><!-- druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.4</version></dependency><!-- 动态数据源 --><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.2</version></dependency><!-- SqlServer 数据库连接包 --><dependency><groupId>com.microsoft.sqlserver</groupId><artifactId>sqljdbc4</artifactId><version>4.0</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-core</artifactId><version>3.4.1</version></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.18</version></dependency></dependencies>
    
  • 感觉又回到了刚学spring框架的那个时候了,做项目基本用开源框架或者公司自己的产品框架开发,很少自己搭spring项目了。

  • 然后修改pom.xml的打包配置选项

        <build><finalName>yuyue</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><includeSystemScope>true</includeSystemScope></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><executions><execution><id>copy</id><phase>package</phase><goals><goal>copy-dependencies</goal></goals><configuration><outputDirectory>${project.build.directory}/lib</outputDirectory></configuration></execution></executions></plugin><!--指定JDK编译版本 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>3.1.2</version><configuration><skipTests>true</skipTests></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><configuration><nonFilteredFileExtensions><nonFilteredFileExtension>woff</nonFilteredFileExtension><nonFilteredFileExtension>woff2</nonFilteredFileExtension><nonFilteredFileExtension>eot</nonFilteredFileExtension><nonFilteredFileExtension>ttf</nonFilteredFileExtension><nonFilteredFileExtension>svg</nonFilteredFileExtension></nonFilteredFileExtensions></configuration><version>3.1.0</version></plugin></plugins><resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource><resource><directory>src/main/java</directory><includes><include>**/*.xml</include><include>**/*.json</include><include>**/*.ftl</include></includes></resource></resources></build>
    
  • 使用yaml配置文件,配置内容如下

    server:port: 8080servlet:context-path: /compression:enabled: truemin-response-size: 1024mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*spring:datasource:druid:stat-view-servlet:enabled: trueloginUsername: adminloginPassword: 123456allow:web-stat-filter:enabled: truedynamic:datasource:master:# 本地url: jdbc:sqlserver://localhost:1433;DatabaseName=Lanshanusername: sapassword: root# mybatis plus 设置
    mybatis-plus:mapper-locations: classpath*:com/yuyue/**/xml/*Mapper.xml#  configuration:#关闭二级缓存,默认开启#    cache-enabled: false#    log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:# 关闭MP3.0自带的bannerbanner: falsedb-config:# 主键类型  0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)";id-type: 4# 默认数据库表下划线命名table-underline: true# 配置逻辑删除logic-delete-field: deletedlogic-delete-value: 1logic-not-delete-value: 0#  这个配置会将执行的sql打印出来,在开发或测试的时候可以用configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplconfiguration-properties:# 配置流程引擎参数,详情可见 DatabaseConfigurationblobType: BLOBboolValue: TRUE# 不要设置库名,否则会出现双库名 bugprefix: ''
    # Mybatis输出sql日志
    logging:level:com.yuyue: debug
    
  • 然后就写相关的实体类,mapper,service,controller。

  • 写完到这里就基本没问题了,可以正常启动。

五、前端框架uni-app修改

前端框架虽然没有从0开始做,还是用的若依的uniapp,但是做了其他额外的工作量,打开首页的页面修改成我的首页,我所新加的页面都要在permission.js中排除掉,要不然会重定向到首页。去掉若依下面的固定栏位。剩下的就是添加接口js文件,然后在页面中将数据的获取方式从模拟值修改为访问后端接口返回。

这些都还是比较简单,过程有点繁琐而已,当前面都改完之后,这个项目最大的难点来了,就是openid的获取。根据微信官方文档所写,获取openid分为两部分,根据appid获取到微信返回回来的code,然后根据code和appid和app密钥获取该用户的openId。需要公众号提供的参数如下:

  • appId
  • app密钥secret

以下介绍对接获取微信公众号登录用户openId的过程

六、对接获取公众号登录用户openId

前提:以上程序开发完成并且配置到服务里面,服务证书访问并申请开启域名访问。

首先需要公众号进行如下的一些配置和操作

  • 配置网页授权域名
    在这里插入图片描述 配置网页授权域名的时候,保存的时候微信会校验一个文件,如下图
    在这里插入图片描述

    下载上图提到的文件,开启域名后需要同步开启80端口访问,然后将文件上传到服务器80端口的根目录,如果不知道根目录位置,可以找一下nginx或者网站的配置项。域名填写的内容如下示例:www.xxx.com,不用加前缀,不用加端口号。然后点击保存,如果提示域名活路径格式不正确说明你上传的文件放错位置了,文件放上去之后,确保访问www.xxx.com/上传文件名可以访问到。

  • 公众号添加IP访问白名单
    在这里插入图片描述

    将服务器的外网ip填写进去即可。

  • 提供公众号的appid和secret

  • 绑定微信公众号的开发者微信号

    作为开发人员,如果不绑定这个东西就属于是隧洞摸黑前行,永远也想不到有多少个坑在等你。
    在这里插入图片描述

    需要开发人员先关注该公众号,然后将你的微信号提供出来,在公众号中进行开发者绑定。

以上,公众号的配置暂告一段落。

接下来,程序开始修改获取openId。

程序修改后,如何验证正确性以及中间过程访问的参数是否正确,这个时候我们需要用到微信开发者工具

在这里插入图片描述

打开这个软件,然后用绑定公众号开发者的微信号登录,访问服务器部署的url,就能看到调用的接口了(做这种对接就不要想着本地调试了)。唯一麻烦的只有每次修改完代码后,需要将代码打包放在服务器然后解压。

  • 根据appId获取微信返回回来的CODE

    访问url:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

    需要修改的参数是:APPID,REDIRECT_URI

    APPID就是以上公众号提供出来的appId,REDIRECT_URI是重定向结果的url,这个重定向是微信官方那边做的,我们不用管如何重定向,需要注意的是重定向的url需要使用javaScript函数encodeURIComponent()进行编码

    示例:

    redirectToAuth() {const redirectUri = encodeURIComponent('https://www.xxx.cn')const authUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+this.appid+'&redirect_uri='+redirectUri+'&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect'window.location.href = authUrl;}// 访问后页面会刷新重定向为
    // https://www.xxx.cn?CODE=xxxxxxxxx
    
  • 处理微信返回来的CODE

    接下来要根据CODE和appid和secret获取到用户的openid,记住,这个过程一定要在后端完成,不可在前端代码完成,这个地方有坑,差点被坑哭了(>_<)。使用前端返回openid,接口会提示跨域异常,没有返回数据。

    首先获取url中的CODE参数

    const code = (new URLSearchParams(window.location.search)).get('code')
    

    接下来发起后端调用,我这里使用hutool的http工具访问,如下示例

    访问url:https://api.weixin.qq.com/sns/oauth2/access_token

    String resultOpen = HttpUtil.get("https://api.weixin.qq.com/sns/oauth2/access_token?" +"appid=" + appid +//公众号ID"&secret=" + secret//公众号密钥"&code=" + code + //前端 传入 code"&grant_type=authorization_code");
    JSONObject jsonObject = JSONObject.parseObject(resultOpen);
    if (jsonObject.containsKey("errcode")) {String s = codeMap.get(code);if(StrUtil.isBlank(s)) {return Result.error(resultOpen);}else{return Result.ok(s);}
    }
    openId = jsonObject.get("openid").toString();
    

    正常返回的参数如下

    {"access_token":"ACCESS_TOKEN","expires_in":7200,"refresh_token":"REFRESH_TOKEN","openid":"OPENID","scope":"SCOPE","is_snapshotuser": 1,"unionid": "UNIONID"
    }
    

    错误返回的参数如下

    {"errcode":40029,"errmsg":"invalid code"}
    
  • 当我们正确拿到这个openid就可以为所欲为了(不是),就可以正常进行后续的业务操作了。

  • 最后让客户将我们项目的访问链接配置在公众号的菜单就可以啦

七、总结

真正开发的时间其实是从周五下午开始,期间我还在忙另一个正在上线的项目。这个功能虽然要求不多,但是涉及到对接,期间的坑属实不少,看着网上一篇有一篇的攻略,却总是抓不住要点,就openid要后端才能获取这个,很多网上教程说直接用前端代码获取,可能之前可以,但是现在不行了。客户下周一验收此功能,可以算得上3天搞定一个公众号对接案例,涉及到对接微信的东西不多,只有一个获取用户openid,这一个小东西就能碰到很多坑。

经过这次项目,可以看得出制定方案选型有多么重要,真正干活其实方向对了很快就出活了,如果方向不对,比如这次公众号开发就是要改造若依框架,可能2周都出不来。

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

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

相关文章

系列十五、BeanDefinition

一、BeanDefinition 1.1、概述 BeanDefinition是一个接口&#xff0c;主要负责存储bean的定义信息&#xff0c;决定bean的生产方式&#xff0c;类似于说明书。后续BeanFactory就可以根据这些信息生产bean了。比如实例化&#xff1a;可以通过反射得到实例对象&#xff1b;比如&…

【版本管理 | Git 】Git最佳实践系列(一) —— LFS .gitignore 最佳实践,确定不来看看?

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

【腾讯云云上实验室-向量数据库】用向量数据库——实现高效文本检索功能

文章目录 前言Tencent Cloud VectorDB 简介Tencent Cloud VectorDB 使用实战申请腾讯云向量数据库腾讯云向量数据库使用步骤腾讯云向量数据库实现文本检索 结论和建议 前言 想必各位开发者一定使用过关系型数据库MySQL去存储我们的项目的数据&#xff0c;也有部分人使用过非关…

Kafka配置SASL认证密码登录

​​​​​​1、修改config/server.properties&#xff0c;添加如下内容 listenersSASL_PLAINTEXT://内网ip:9092 advertised.listenersSASL_PLAINTEXT://外网ip:9092 security.inter.broker.protocolSASL_PLAINTEXT sasl.mechanism.inter.broker.protocolPLAIN sasl.enabled.…

Vue解析器

解析器本质上是一个状态机。但我们也曾提到&#xff0c;正则表达式其实也是一个状态机。因此在编写 parser 的时候&#xff0c;利用正则表达式能够让我们少写不少代码。本章我们将更多地利用正则表达式来实现 HTML 解析器。另外&#xff0c;一个完善的 HTML 解析器远比想象的要…

高性能Mysql第三版学习(一)

学习目标&#xff1a; 高性能Mysql第3版 学习内容&#xff1a; MySQL架构与历史Mysql基座测试服务器性能Schema与数据类型优化创建高性能的索引查询性能优化Mysql高级特性Explain 学习时间&#xff1a; 周一至周五晚上 9点—晚上10点周六晚上9点-10点周日晚上9 点-10点 学习…

鸿蒙开发-ArkTS 语言-基础语法

1. 初识 ArkTS 语言 ArkTS 是 HarmonyOS 优选主力开发语言。ArkTS 是基于 TypeScript (TS) 扩展的一门语言&#xff0c;继承了 TS 的所有特性&#xff0c;是TS的超集。 主要是扩展了以下几个方面&#xff1a; 声明式UI描述和自定义组件&#xff1a; ArkTS使用声明式的方式描述用…

java计算下一个整10分钟时间点

最近工作上遇到需要固定在整10分钟一个周期调度某个任务&#xff0c;所以需要这样一个功能&#xff0c;记录下 package org.example;import com.google.gson.Gson; import org.apache.commons.lang3.time.DateUtils;import java.io.InputStream; import java.util.Calendar; i…

JWT和Token之间的区别

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…

鸿蒙开发之android开发人员指南《基础知识》

基于华为鸿蒙未来可能不再兼容android应用&#xff0c;推出鸿蒙开发系列文档&#xff0c;帮助android开发人员快速上手鸿蒙应用开发。 1. 鸿蒙使用什么基础语言开发&#xff1f; ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript&#xff08;简称TS&#xff09;基本语法风…

vcsa6.7 5480无法登录

停电维护硬件后&#xff0c;发现vcsa异常&#xff0c;https://ip:5480无法登录&#xff0c;https://ip/ui正常&#xff0c;ssh登录页正常 kb资料 通过端口 5480 登录到 VMware vCenter Server Appliance Web 控制台失败 (2120477) 操作过程 Connecting to 192.16.20.31:22..…

跑步运动耳机哪个牌子好?运动型无线耳机排行榜

​运动耳机是我们运动时不可或缺的装备&#xff0c;它可以让你享受高品质的音乐&#xff0c;还提供了高舒适佩戴体验以及稳定的连接。然而面对市面上层出不穷的运动耳机&#xff0c;到底哪款更值得入手&#xff1f;今天我为大家推荐几款市面上备受好评的运动耳机&#xff0c;是…