140

聊聊二维码登录 - xixicat - SegmentFault

 4 years ago
source link: https://segmentfault.com/a/1190000012446715?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

聊聊二维码登录

发布于 2017-12-15

本文主要来研究一下二维码登录的相关场景和原理。

主要的场景有如下几个:

  • app扫二维码登录pc版系统

比如微信web版,在手机端微信登录的前提下,扫二维码确认,自动登录网页版。这里的app可以分为两大类,一个是自有的app,一个是第三方的app。

自己的app自有认证体系,在登录前提下完成pc端的扫描登录。
第三方app扫描登录场景,比如使用手机端的微信APP扫描登录PC端系统,这种情况下,一般是利用微信的oauth体系,服务端完成自有账户体系与微信账号的绑定,然后实现PC端的自动登录
  • app扫二维码作为双因素验证

比如微信公众号平台,在账户密码登录PC端的情况下,再使用手机端微信登录的前提下,扫描二维码再次确认,登录网页版

  • Secure QR Login (SQRL)

完全使用二维码登录,替代用户密码。这个有SQRL协议及相关实现。

以下所有的都基于这个前提,就是手机app已经登录,自带有登录的凭证,然后要扫描登录pc端的系统

  • 打开pc端显示登录二维码(pc端未登录的前提下)
这个时候请求服务端生成一个登陆二维码
服务端生成二维码,该二维码包含了这个pc端的唯一标识,比如sessionId,或者是新生成一个uuid跟这个sessionId关联
  • pc端同时开启轮询(有长连接等其他实现,这里以轮询方式介绍)
获取二维码之后,pc端开启定时轮询,轮询二维码的状态,主要有如下状态:NEW,SCANED,CONFIRMED,REFUSED,EXPIRED
  • 手机端扫描二维码
手机端已经登录的情况下,扫描网页二维码,二维码状态变为已扫描,然后手机端跳转到确认页面
  • 手机端确认
手机端扫描二维码之后,点击确认,二维码状态变为确认
  • pc端跳转成功/二维码过期/拒绝
二维码状态变为确认之后,跳转自动登录,完成PC端登录态建立
如果app端拒绝这次请求,则二维码状态变为被拒绝,不再轮询
如果二维码状态在一定时间没有变化,则显示二维码过期,不再轮询

PC客户端

  • 请求登录二维码
  • 轮询二维码状态
  • 跳到到登陆后的页面

手机客户端

  • 扫描登录二维码
  • 生成登录二维码,绑定二维码与pc客户端
  • 处理二维码轮询
  • 处理手机端扫描二维码
  • 处理手机端确认二维码登录
  • 处理pc端自动登录

PC端如何自动登录

这个问题相当于同一个帐号多设备同时登录的问题

在二维码被具有登录态的app端扫描确认之后,PC端如何完成自动登录。有如下几个方案:

  • session拷贝
其实就是在原来基于账号密码的登录鉴权逻辑基础上,新增支持无需账号密码的登录。也就相当于绕过了基于用户名密码,内部重新设置了一个登录态
如果是基于session的鉴权,相当于基于原有的一个已经鉴权的session,拷贝信息到另外一个新的session中,在server端关联
  • 复用已有token
如果是基于token的鉴权,一种方案就是复用token,让pc端也复用手机app端的token,这样的好处是原来基于token的鉴权逻辑都不用改
  • 仿照oauth授权颁发新token
整个过程其实有点像oauth,pc端是client,server端是资源和认证中心,手机端是具有登录态的用户。手机端扫描二维码,然后用户确认授权,server端给pc端颁发token,然后pc端就可以访问server端的资源了。这种就在原来的认证基础上支持另外一类oauth的token校验,貌似有点复杂
另外一个变形是新颁发token,但跟app端的token有个关联映射,最终鉴权的时候还去找原来授权的token去鉴权,这样的好处是原来的token失效,经过它授权的token也失效

二维码过期

一种是基于redis来做过期,一种是使用数据库,但是设置expired time来判断

QRLJacking全称Quick Response Code Login Jacking,是session劫持的一种。

具体是怎么劫持的呢,假设攻击者将web登录二维码伪装为公众号二维码,让用户去扫描,用户一不小心点击确认,攻击者的就可以登录用户的web系统,或者利用那个token/session去盗取用户的相关信息或做相关操作。

  • 二维码超时机制

二维码增加超时机制之后,会增加攻击者攻击的难度,不过攻击者也可能利用脚本去自动刷新二维码

二维码扫描一定要有这个确认的页面,明确告知用户要做的操作,假设没有确认这个环节,那么是极其容易上当的。另外,二维码扫描确认之后,再往用户app或手机等发送登录提醒的通知,告知如果不是本人登录的,则建议用户立即修改密码

  • Sound-based Authentication

确认阶段改为双边语音确认,而不是简单的用户点击确认按钮。语音是根据用户id、二维码id等加密生成,在app端播放,然后pc端语音识别之后才能完成整个登录过程。这个可以有效防止远程攻击。同样的思路,改语音为one time password也行,增加了确认过程的复杂度,也就增加了攻击的难度。

二维码扫描登录是个挺潮流的功能,这要求既有系统增加改造,也要求针对这种形式的登录带来潜在的攻击进行安全防范。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK