扫码登录是如何实现的?
二维码信息里主要包括唯一的二维码ID,过期的时间,还有扫描状态:未扫描、已扫描、已失效。
扫码登录流程
用户打开网站登录页面的时候,浏览器会向二维码服务器发送一个获取登录二维码的请求。二维码服务器收到请求后,会随机的生成一个uuid,通常是唯一的。将这个uuid作为key存储到Redis服务器中,同时会设置一个过期时间,过期之后用户就要重新网页刷新来获取。之后会将这个uuid和本公司的验证字符串和在一起通过二维码生成接口生成图片,将二维码图片信息和uuid返回给浏览器,浏览器拿到uuid和图片之后,每隔一定时间就向服务器发送以恶判断登录是否成功的请求,请求,请求中会携带uuid作为当前页面的标识符。
用户拿起手机扫描二维码之后,就会得到二维码中包含的验证信息和uuid,由于手机端已经进行过登录验证,在访问手机端服务器的时候参数中都会携带一个用户信息token,这个token实在第一次手机登录过程中产生并且长期有效的。手机端服务器通过这个token就可以解析出用户的类似于userId等信息。然后手机端服务器会将解析出来的数据作为参数向二维码服务器发送登录请求,二维码服务器收到请求后会对参数进行校验,确定是否为用户登录请求接口。如果是就返回给手机一个确认信息。手机端收到消息之后,登录确认框会显示给用户,用户进行登录确认之后手机再次发送请求,redis服务器拿到信息之后,会将刚才uuid的key的value设置未userId。
这样浏览器再次发送请求的时候就可以在redis服务器重拿到用户的id,并调用登录方法生成一个浏览器token。浏览器再发送请求,就会将用户信息的token返回给浏览器。
流程图
Tip 提示:
这里存储用户id而不是直接存储用户信息是因为,手机端的用户信息,不一定是和浏览器端的用户信息完全一致。
传 token 是为了安全,token是被加密的,直接传 userId可能有被窃取的风险。
注意点:
- 认证成功后,会对当前用户数据进行加密,生成一个加密字符串token,返还给客户端(服务器端并不进行保存)
- 浏览器会将接收到的token值存储在Local Storage中(通过js代码写入Local Storage,通过js获取,并不会像cookie一样自动携带)
- 再次访问时服务器端对token值的处理:服务器对浏览器传来的token值进行解密,解密完成后进行用户数据的查询,如果查询成功,则通过认证,实现状态保持,所以,即使有了多台服务器,服务器也只是做了token的解密和用户数据的查询,它不需要在服务端去保留用户的认证信息或者会话信息,这就意味着基于token认证机制的引用不需要去考虑用户在哪一台服务器登陆了,这就为应用的扩展提供了便利,解决了session扩展性的弊端。