0 前言
在我们日常逛各个网站的过程中,部分网站需要登录,才能进行资源访问,这是很普遍的现象。
而如今,随着微信普及程度大大增加,通过微信扫描网站的二维码进行登录,不仅减少了用户注册成本,而且能够实现用户的引流
,极大提高用户体验。
当前通过微信扫码登录网站的方式,主要有两种
。
一种是通过微信开放平台
申请接入网站应用
,然后通过微信开放平台的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框架
,这里不赘述。
下图二维码,是我们通过测试号
,实现的小小的Demo。
访问第四项微信公众号登录
,即可体验完整的登录流程,其中需要关注测试号,测试人数上限100人。当然前三项也可以体验一下。
以上就是本文的主要内容。如果有具体的业务需求,可以联系我们。