扫码登录的基本技术细节

refer:https://my.oschina.net/u/4231722/blog/3154805 常见的各大网站扫码登录: image.png 各大网站的扫码登录技术细节都是很相似的: 扫码登陆.png PC端浏览器打开淘宝网的登录界面,选择二维码登录; PC端淘宝服务器接收到请求,随机算法产生Uuid,将Uuid作为key值存入数据库当中,此外,会设置Uuid的expire时间; PC端淘宝服务器根据Uuid和公司唯一标识生成二维码; PC端淘宝服务器将生成的二维码以及Uuid作为请求的response发送给PC端浏览器; PC端接收到response之后,根据二维码图片地址download相应的二维码并在UI上显示,并且开启轮询模式,定时根据Uuid查询当前扫码登录的status; 用户在手机端淘宝App扫描二维码; 根据二维码提供的Uuid,带上手机端登录的token信息,发送验证的request到Mobile端淘宝服务器; Mobile端淘宝服务器收到request,compare参数中的验证信息; 验证通过,告知手机端淘宝App; Mobile端淘宝App收到验证通过的信息,UI显示 确认登录的页面; 用户确认登录,Mobile端淘宝App发送确认登录请求给Mobile端淘宝服务器; Mobile端淘宝服务器收到确认登录请求后,将Uuid和从token里面解析出来的userId一起存入数据库; 将UserId作为对应key值为Uuid的value值存入数据库中; 轮询一直在继续,PC端淘宝服务器此时可以在数据库中读取到Uuid对应的userId,将userId封装成token,返回给PC端浏览器; PC端浏览器拿到token信息,根据token信息进行redirect成功登录。 以淘宝页面扫码登录为例, PC Browser请求二维码 request二维码.PNG 对应Get API的response,包含二维码图片的source和Uuid(Uuid是当前页面/窗口的唯一标识) request二维码的response.PNG 拿到二维码图片的source路径之后,后续请求的image资源 二维码image resource.PNG 根据Uuid轮询查询登录状态 轮询.PNG 没有扫码时的轮询结果返回 轮询的response.PNG 二维码超时的轮询结果返回 二维码expire失效.PNG 7.扫码完成的轮询结果返回 扫码成功的轮询返回.PNG 8.登录成功的轮询结果返回 { "code": "10006", "success": true, "url": "https://login.taobao.com/member/loginByIm.do?uid=XXX&token=XXX&time=1530179143250&...." } 一些思考: 为什么用到了轮询模式而不是消息通知模式(WebSocket)? 轮询模式程序编写比较容易(几乎不用做什么特殊处理), 它虽然相比消息通知模式更加cost 前后端的effort[浪费带宽和服务器资源,前端要定时send Get API request, 后端要在accept request之后进行处理],但是在这种应用场景下, 前端可以custom查询间隔,设置expire时间,后端所做的处理也只是查询database,所以总的cost并没有太大。 在扫码登录的应用场景下,轮询模式中可以进行的优化有哪些? custom查询间隔, 未扫码时可以custom每次查询的时间间隔,时间越长后续查询间隔越长; 设置expire时间, 每个Uuid都有固定的expire时间,超过这个时间还没有扫码则当前二维码失效; 后端可以根据扫码情况阻塞前台请求,优化轮询及减少前端的无效轮询