1.研究知乎与微信的实现
首先研究知乎扫码登陆
在电脑端打开知乎,进入浏览器控制台Network,很明显可以看到知乎通过定时请求来判断当前的二维码状态。
经过初略观察,发现以下信息:
打开扫码登陆页面后
首先会发送POST请求,来请求相关信息。地址:
https://www.zhihu.com/api/v3/account/api/login/qrcode
然后通过上一步请求的信息获取二维码图片。地址:
https://www.zhihu.com/api/v3/account/api/login/qrcode/R4F3Suw4SNqdncbT/image
将二维码解析得到的地址:
https://www.zhihu.com/account/scan/login/QWoTFB3_Q_GsIIof
页面定时发送请求地址:
https://www.zhihu.com/api/v3/account/api/login/qrcode/R4F3Suw4SNqdncbT/scan_info
再来看看微信的
打开微信网页首先请求https://login.wx.qq.com/jslogin获取二维码uuid
接着请求https://login.weixin.qq.com/qrcode/{uuid}获取二维码图片
然后请求https://login.wx.qq.com/cgi-bin/mmwebwx-bin/login来获取二维码状态
不过微信这边每次请求如果不进行操作的情况下保持连接到25秒左右进行响应
2.动手实现
完整代码放在:https://gitee.com/baojuhua/node_simples/tree/master/node_simple_qr_login
因为会话之间是独立的,所以需要通过某种手段将其打通,所以我这边直接在代码中通过声明全局CacheSession变量进行操作(当然你也可以使用req.sessionStore.sessions)。
实现原理也非常简单,首先需要移动端登陆先成功来模拟手机应用登陆成功的情况。
接着在浏览器进行访问登陆页面,然后生成扫码登陆相关信息保存到CacheSession并且通过标识与session会话进行关联。
然后移动端扫码二维码访问地址,通过解析获得CacheSession中对应的数据,将相关数据显示到移动端等待用户确认。
再然后是用户发送确定登陆或拒绝登陆再或者是不进行操作的情况:
- 如果点击了确定,前端发送请求给后端,后端会修改
CacheSession中数据,等待电脑端定时请求获取到数据后进行登陆跳转 - 点击拒绝与点击确定的效果差不多,只不过不会跳转到登陆而已
- 因为移动端访问扫码二维码获得的地址后会修改
CacheSession中记录的超时值,如果长时间未操作就会将状态修改为超时状态
代码中的路由说明:
| 路由 | 说明 |
|---|---|
| / | PC端首页(通过浏览器标识判断客户端类型进行重定向) |
| /login | PC端扫码登陆页面 |
| /qrcode | PC端生成二维码相关信息 |
| /qrcode/img/:code | PC端生成二维码图片 |
| /qrcode/scan_info/:code | PC端定时获取扫描状态信息 |
| /app_home | 移动端首页 |
| /app_login(get) | 移动端登陆页面 |
| /app_Login(post) | 移动端登陆请求 |
| /account/scan/:code | 移动端同意登陆页面(显示登陆端ip、浏览器标识等信息) |
| /confirm/scan/:code | 移动端确定取消登陆 |
二维码状态说明:
| 状态(status)值 | 说明 |
|---|---|
| -1 | 系统异常 |
| 0 | 等待扫描 |
| 1 | 已扫描等待确定 |
| 2 | 移动端确定 |
| 3 | 移动端确定超时 |
| 4 | 会话过期 |
| 5 | 移动端拒绝 |
测试
这里分别用 Chrome 浏览器与 火狐 浏览器进行测试
Chrome模拟电脑端
火狐模拟手机端
二维码过期效果
模拟手机端登陆
手机端同意登陆
手机端同意拒绝登陆
手机Opera浏览器测试(手机端效果)
手机Opera浏览器测试(电脑端效果)











网友评论