目录
1、前期准备
公众号和小程序相互关联
准备公众号文章
注册公众号测试号
微信静默授权的独立html 文件
2: 小程序代码
webview页面代码
小程序首页代码
3:后端代码
1:增加公众号配置项
2:读取公众号配置项
3:增加微信公众号工具类
4:增加微信用户基本信息类
5:增加跳转html页面的接口
6:HttpClientUtil网络请求工具类
7:使用步骤
4:上线配置
这篇文章讲的是uniapp微信小程序【引导用户关注微信公众号】,【判断用户是否关注公众号】,用的是后端是 java springBoot,不是自己想要的网友可以关闭页面了。
需求背景:客户的下单系统原本是建立在微信公众号的,现在要求换成小程序,但涉及到消息推送的还是用公众号的推送,所以要求用户进入小程序的时候判断是否已经关注公众号了,没有关注就提示,并引导用户关注。
一收到需求,鸭蛋,没弄过,纯纯小白,第一件事当然就是找度娘了,查出的资料五花八门,各种各样,各种不完整,缺失关键代码和步骤,尤其【C】SDN,一大堆都是抄的,真TM的痛苦,没办法,我太菜了。
现在说一下我的实现方式:
引导关注公众号:微信小程序有个自带的引导用户关注微信公众号的组件,official-account,使用简单,就是限制太多了,必须指定方式打开小程序才显示,完全不符合客户需求,后来我是跳转到公众号的一篇文章,里面有公众号卡片和二维码,让用户进行关注。
判断是否关注公众号:网上基本清一色就是建表存关注的用户信息,然后定时拉取更新表。还有就是主动拉取微信公众号全部关注的用户,然后通过unionid进行判断是否关注。我一看就觉得完全没法用,公众号的用户体量几千万,要是每次判断都是去拉取全部用户信息,然后再一个个对比,这时间得多久,性能也会吃力。其实来来回回主要的难点就是在于小程序怎么获取到用户在公众号的openId,我的做法是跳转一个空白登录页,获取到微信公众的loginCode后,后台解析获取到对应的openId,再用公众号的openId去判断是否已经关注,然后再跳转回对应功能页面,对于用户来说,就是多了一次跳转,时间也就是1秒多这样,当然不是在首页进行操作,具体可以认真看完。
1:一个微信公众号,一个微信小程序,以及他们的appid和AppSecret(怎么拿到自己百度吧,也不是很难)。
2:微信公众号的一篇引导关注文章。
3:一个独立的html文件,里面是写微信公众号静默登录代码的。
4:在微信公众号后台管理那里,注册一个测试号,用作等会静默登录测试用。
5:把自己的微信号都添加成公众号和小程序的开发者。
搜索微信公众平台,扫码登录选择公众号,进入公众号管理后台
在微信管理后台把自己的微信号加入到公众号的开发者里面。
小程序如果你能登录到管理后台,说明你已经是项目成员,不然让管理员把你加到项目成员里面就可以了。
首先是小程序和公众号必须是同一个主体下的,并相互关联,如果不相互关联,小程序的web-view组件是打不开公众号的文章的,比如出现下面这种情况。
官方文档链接:小程序webview访问公众号文章提示非业务域名 | 微信开放社区
》》搜索微信公众平台,扫码登录选择公众号,进入公众号管理后台,进行关联小程序。
》》搜索微信公众平台,扫码登录选择小程序,进入小程序管理后台,左下角设置,进行关联公众号。
微信公众号发一篇引导关注文章,放个二维码,公众号卡片啥的,然后去复制这篇文章的链接,这一步看似简单,实则有坑,按常规的步骤复制,得到是一个短链接,比如下面的步骤得出链接是:https://mp.weixin.qq.com/s/7wYtVJc6XXXXXXXXXXXX...
这样的链接你在微信开发者工具是完全没有问题的,一到真机上面就不行。
我们必须复制出一个长链接,有参数的。首先电脑端微信打开公众号主页,找到对应文章,右键选择默认浏览器打开,然后再复制浏览器上的链接,就会得到一个长链接,比如:
https://mp.weixin.qq.com/s?__biz=MjM5&mid=28192&idx=1....
后面带有_biz,mid这种参数的
拿到引导关注的文章链接,先找个地方保存好,后面要用。
接下来是注册一个测试公众号,搜索微信公众平台,扫码登录选择公众号,进入公众号管理后台。
里面步骤
1【记下测试号的appid和appsecret】
2【设置JS接口安全域名】
3【用自己微信扫码关注测试号】
4【体验接口权限表里面找到网页授权获取用户基本信息,右边修改授权回调页面域名】
两个域名(js接口域名和授权回调域名)也可以保持一致。
测试号的域名可以直接填本机ip加端口号,记住不要加http或https开头,比如 192.168.0.41:8080
新建一个文本文件,把下面代码放进去,然后文件重新名,后缀改成html即可,找个地方放好。
具体思路是:用户通过webview组件访问我们写的html页面,首次进入,页面会重定向到微信授权,自动授权完成后,再次自动重定向回此html页面,此页面拿到code,然后关闭此html页面,跳转微信公众号文章页面,用户进行关注,然后用户点击返回的时候,我们通过拿到的code去获取微信公众号的openId,进而通过openId判断用户是否已关注。流程图大致如下吧。
如果要了解微信网页授权,也就是html页面里面的window.location.href重定向授权链接参数,可以看下面的文档,这里不详细说明了。
官方的网页授权文档:网页授权 | 微信开放文档
我这边的做法是用户表里面有个字段记录微信公众号的openId,用户登录进入首页后,如果此字段没有值,则说明此账号没有绑定过微信公众号。这里可能有人会说,如果这个账号在其他微信号上面登录呢,也就是在A微信登录,并关注公众号,然后又去B微信登录,此时表里的字段存的是A微信的openId,B微信实则没有关注,这里其实就要看对应系统业务需要了,我这边是要关注公众号后,然后利用公众号推消息,所以我的小程序里面会有一个页面是用来专门处理换绑,也就是从A微信的关注换绑到B微信的关注,但现在写教程,我就不说具体业务了,只说怎么拿到openId,然后判断有没有关注,如果你是需要每次都判断当前微信有没有关注,那把具体入口写在登录页吧,比如用户点击登录跳转登录页,你可能是跳转/pages/login页面,那改成直接跳转webview页面,然后访问我们写的html授权页面,授权完成拿到code后,html页面代码里面的wx.miniProgram.redirectTo跳转到小程序登录页去,那你小程序的登录页也就拿到code了,从而可以判断是否已经关注。
回归正题
我们登录成功进入首页,判断openId如果没有值,则则给出关注提示。点击提示跳转到webview组件页面,访问我们写的html页面,一连串执行后,用户点击返回会回到首页,首页接收微信公众号的登录code,并调接口进行解析。如果有openId,我们也可以发出请求,查此openId的微信号有没有关注公众号。
记得在pages文件配置上这个页面
1:判断登录后有表里没有微信公众号的openId,如果有onLoad方法请求后端,获取微信是否关注公众号,如果没有,显示提示。如果表里没有微信公众号的openId,直接显示提示。
2:点击提示跳转webview页面。此链接打开的是我们写的那个html页面,本地写成自己的ip,上线后用线上域名。后端部分后面再说。
注意:http://192.168.0.41:8080/api/express/member/wxPublicLogin是访问我们写的html页面的链接,那么前面我们写的html文件里面,REDIRECT_URI的值也是这个链接。
3:跳转webview页面后,一系列执行,进入公众号文章页面。关不关注那是用户的事,我们只负责引导。
4:点击左上角返回,会设置缓存code,然后回到首页。code是在webview页面的onUnload方法设置的。首页的onShow方法写上接收缓存。
onBindingWxPublic方法是把code传回后端,然后解析出openId,然后查询是否已关注公众号,关注了就记录openId到表里面,没有关注就不管了,接口返回 boolean 是否已关注就行了。
建一个WxPublicProperties类
类名:WxPublicUtil,里面的HttpClientUtil类放在最后面
类名:WxUserInfoVO,里面有个微信公众号最近一次关注的时间subscribeTime,那个时间戳要转换成long再乘以1000才是完整时间,有需要这个时间的话,注意一下。
get和set方法我去掉了,自己加一下吧。
记得先用@Autowired注入WxPublicProperties,这个接口是读取我们写的html页面,并返回,相当于是用户调用这个接口是进入我们写的html页面。IOUtils.toByteArray是把输入流转成字节,如果没有这个工具类,就手写吧,实在不懂百度【java输入流转byte字节数组】。
这个接口记得不要被权限拦截,也就是没有登录也可以访问。
首先前端是调/member/wxPublicLogin接口进入html页面,然后html页面拿到code返回到具体功能页,这个时候就看你业务了,公众号的登录code都拿到了,你想怎么干就怎么干了。
用code换取openId,并用openId获取用户基本信息。记得先@Autowired注入WxPublicUtil,userbaseInfo里面就有openId等关注信息。字段subscribe = 1 就是已关注,0就是未关注。
1:配置文件那里,appid,secret等都要换成正式公众号的,loginFilePath换成服务器或者其他容器存放的地址。
2:登录公众号的管理后台,填写网页授权域名,填正式环境的域名,它会给你一个文本文件让你放在域名根目录,照做就行了。
3:微信公众号增加获取access_token接口ip白名单,把服务器的ip加上去。
如果获取access_token出现这个错误就是ip白名单没有配置 。复制错误信息里面ip去配置就行了。
4:登录小程序后台管理,把服务器域名和业务域名设置上,就是配置上服务器的域名,不然webview打不开我们写的html页面,如果webview页面打不开公众号文章页面,就去看官方文档吧。
官方文档链接:小程序webview访问公众号文章提示非业务域名 | 微信开放社区
那个html页面是个无感登录页面,我们在这个页面获取到的code,去换取微信用户信息的时候,只能拿到openId和关注时间,其他信息(昵称,头像等)都拿不到,如果想要获取到其他信息,html文件里面的window.location.href重定向到微信授权链接,scope参数换成snsapi_userinfo,这样获取到的code就能拿到其他信息,不过这样话,进入这个html页面,会弹出用户信息授权确认的,比如下面这个。
应该差不多了吧,可能会有些遗漏,毕竟步骤是在是太多了,总得就是本地用测试号,上线换正式公众号。 值得注意的是,通过那个html页面拿到的登录code是有时效的,只有几分钟,如果用户在公众号文章页面停留太久,那这个code可能就过期了。具体怎么解决,是重新再跳一次无感登录页面,还是提示用户,你看着办吧。
目前上线后存在一个问题,电脑版小程序在html页面拿到登录code后跳转微信文章页面,有大概率跳不过去,就下面这个代码有可能没有反应,安卓和ios都没有问题,不知道啥情况,有解决的可以留言一下。
终于码字完了