结论:这是微信系的惯用做法,原因是——安全。
前言
本文从技术原理上说说,微信为什么要这么做,且非做不可。
从安全性上看,用手机扫码,高于手机短信验证码,或账密输入。
扫码过程都发生了什么
下面主要从二维码生成、手机扫码确认、登陆成功说明。下图是示意图。
1 – 客户端与服务器的配合
首先用户打开微信客户端,向服务器发送获取登录二维码的请求。
服务器收到请求后,随机生成一个uuid,将这个id作为key值存入redis服务器,同时设置一个过期时间,再过期后,用户登录二维码需要进行刷新重新获取。
同时,将这个key值和验证字符串合在一起,通过二维码生成接口,生成一个二维码的图片。然后,将二维码图片和uuid一起返回给用户。
微信客户端拿到二维码和uuid后,会每隔一定时间向服务器发送一次,登录是否成功的请求。请求中携带有uuid作为当前页面的标识符。
那么,服务器只存了个uuid在redis中作为key值,怎么会有用户的id信息呢?这里确实会有用户的id信息,这个id信息是由手机服务器存入redis中的。
2 – 手机端与服务器的配合
微信客户端拿到二维码后,将二维码展示出来。用户拿出手机扫描二维码,就可以得到一个验证信息和一个uuid。
由于手机端已经进行过了登录,在访问手机端的服务器的时候,参数中都会携带一个用户的token,手机端服务器可以从中解析到用户的userId。
这里从token中取值而不是手机端直接传userid是为了安全,直接传userid可能会被截获和修改,token是加密的,被修改的风险会小很多。
手机端将解析到的数据和用户token一起作为参数,向服务器发送验证登录请求。
服务器收到请求后,首先对比参数中的验证信息,确定是否为用户登录请求接口。如果是,返回一个确认信息给手机端。
手机端收到返回后,将登录确认框显示给用户。用户确认是进行的登录操作后,手机再次发送请求。服务器拿到uuId和userId后,将用户的userid作为value值存入redis中以uuid作为key的键值对中。
3 – 登录成功
客户端再次发送请求的时候,服务器就可以得到一个用户Id,并调用登录的方法,生成一个客户端的token,在客户端再次发送请求的时候,将用户信息返回给客户端,登录成功。
这里存储用户id而不是直接存储用户信息是因为,手机端的用户信息,不一定是和客户端的用户信息完全一致。
结语
比单纯的账密登录,扫码登录使用了一台登录的设备,授权另一个设备登录,从硬件上杜绝了很多不稳定因素。
这也是很多大型的网站通用做法,比如淘宝、支付宝、阿里云等,使用手机端授权,登入其他设备。
偶是@程序员小助手,持续分享编程与程序员成长相关的内容,欢迎关注~~