基于服务号的微信扫码关注公众号登录网站原理分析
当前通过微信扫码登录网站的方式,主要有两种。
一种是通过微信开放平台申请接入网站应用,然后通过微信开放平台的API进行登录。这种登录方式的直观体验是扫描网站二维码后,手机微信端弹出的是一个网页,显示具体的网站应用名称,用户可以同意登录或拒绝登录。
如下图所示。

这种登录方式,实现原理最简单,实现难度低。但微信开放平台,不支持个人用户注册,并且认证账号需要300¥/年,创建网站应用需要审核。
另一种是通过认证通过的微信服务号的生成带参数的二维码,进行扫码、识别身份并登录。这种登录方式的直观体验是扫描网站的登录二维码后,跳转至公众号卡片页面,关注公众号后,网站即可实现登录。此外,如果已经关注了公众号,再次登录时,扫码登录的二维码,将直接进入公众号,网站同时登录成功。与上一种方式类似,个人不支持申请服务号,并且认证服务器需要300¥/年。但通过这种方式登录网站的最大的好处,可以实现引流。
接下来将分析这种通过服务号的网站登录方式。
1 准备工作
实现此功能,需要准备如下:
一个认证通过的服务号;
一台服务器;
一个已备案的域名;
首先是认证通过的服务号,是项目上线的必备。
如果仅仅是技术学习,可以申请测试号。申请网址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
然后是服务器,需要安装Redis。
最后是域名,必须通过备案,否则微信后台的服务器地址,不允许添加此域名。
将此域名下的接收事件消息的接口,添加至公众号后台→开发→基本配置→服务器配置,并开启,如下图:

2 原理分析
首先给出本文解决方案的整体扫码登录过程的时序图:

其核心流程如下:
1、用户打开浏览器,进入登录页面时,需要通过自己服务器返回登录页面的资源。在返回资源之前,自己服务器会针对当前的用户(浏览器客户端Session),生成一个独一无二的KEY值,将此KEY值与生成的用户未登录状态初始参数数组存入Redis,同时将此KEY值通过服务号的生成二维码接口,生成一个带此KEY值的二维码,并返回至用户浏览器。
如下图所示:

2、这时,浏览器显示成功登录二维码。浏览器每隔2秒,向自己服务器询问该用户是否已扫码并关注公众号。自己服务器作出相应的应答。
如下图所示:

3、用户打开手机,扫描二维码,点击关注按钮后,微信APP向微信服务器发送了该关注事件的所有信息,微信服务器将此关注事件的用户信息以及所扫描的二维码参数,通过POST方式发送至自己服务器的事件接收API。
如果用户已经关注了公众号,则直接进入公众号,同时也将上述信息发送至自己服务器的事件接收API。
如下图,事件KEY值和发送方账号是我们需要的数据。

4、自己服务器接收到了微信服务器的事件消息,对该消息进行解析,获取KEY值和登录用户的OpenID。然后根据OpenID,通过获取用户信息的接口,获取用户的基本信息(只有昵称、性别、头像URL,这些都是公开信息),将这些信息,根据KEY值,重新存入Redis数据库,并修改该用户的登录状态。
5、用户端浏览器再次轮询时,发现用户的登录状态变为已登录状态,则可通过相应的接口拉取用户信息,并进行登录的后续操作。
在这整个过程中,浏览器和自己服务器是始终保持通讯状态的,以及时获取用户的登录结果。
这个过程,有这么几点需要注意:
关于保持通讯,除了使用基本的轮询,还可以使用长轮询、长链接、websocket等技术实现。
关于生成的带参数的二维码,可以设置有效期,一般有效期设置几分钟即可。
关于客户端浏览器,应该对二维码有效期的结果做出判断,即二维码失效后,将停止轮询,并提示用户重新获取二维码进行登录,以降低服务器的压力。
如下图所示:

3 具体实现
第二部分已经对整个流程进行了详细分析,技术实现难度不大,主要需要掌握GET、POST请求、Redis数据库操作、XML数据解析与发送等技术,以及服务器配置和项目部署技术。
关键具体的技术实现,有太多的选择,可以使用SSM、Spring Boot等Java框架,也可以使用TP、Laravel等PHP框架,这里不赘述。
参考文档:
- CSDN文章:https://blog.csdn.net/cxh_1231/article/details/116142670
