扫码登录

由于公司目前拥有了B/S和C/S两种运营方式,为了方便(模仿)简化用户登录流程,我们可爱的P们就有了扫码登录的需求,并且要求在2周之内搞定上线。于是气急败坏之下决定先把流程梳理一遍,算是一个对比较有趣的需求进行一个记录。

目前的服务结构为:APP->APP服务器->核心系统webApi<–>核心系统<-网页。
因此针对这种结构考虑扫码登录这种容易受到攻击、PV量还大的业务,需要考虑几个安全因素:

  1. 短时大数次的非正常二维码请求。
  2. 短时大数次的非正常恶意撞库请求。
  3. 可能发生的并发同二维码扫码请求。
  4. 如何嵌入到现有的登录流程中。
  5. 前端高PV的二维码状态轮询。

让我们先来看一下构思好的扫码流程轮询方式的时序图。
图1. 扫码登录基本时序图
将上图定义为:图1. 扫码登录基本时序图

基本想法很简单,然后是关键的一点,也即如何融合进现有的登录流程。因为扫码登录相当于是受信任的令牌周转,跟用户手动输入用户名密码不同,这个过程中完全没有用户名密码参与。这就需要app在扫码之后,把app端当前登录用户信息写入到某个地方,再使用进行登录。此时,就相当于直接使用用户信息搜索数据库,完成登录的过程,但是没有密码

看了一下现有的登录流程,都是围绕着密码转的,如果抛开密码,那么现有的复杂的登录流程就要被割裂而实现另一套登录流程。那么在将来维护登录的时候,会增加成本。

最后通过代码追踪综合考量下来,在原有登录逻辑中,增加扫码登录的部分判断分支,由于原登录流程封装的还可以,因此方便扩展以及修改底层逻辑。还算比较喜人,不同的地方在于:

  1. 跳过验证。
  2. 跳过密码判断。
  3. 跳过一些其他的安全性异常检测。

接着就需要考虑最开始需要考虑的安全性问题了:

1、短时大数次的非正常二维码请求:此处为web端使用的问题,Ajax部分。使用Redis对IP进行记录,限定时间区间为10秒,如果10秒内的请求次数超过40次,将会被锁定一定时间,定为1分钟。
2、短时大数次的非正常恶意撞库请求:此处为web端轮询的问题,Ajax部分。单次guid的撞库概率低的可怜,但是如果考虑数据库增量不清库的话,可能就真的让别人中大奖了。因此可以考虑再加一层签名,让撞库概率再降低一个n次方。同时也可以在签名验证失败的时候直接返回而不查库或者缓存。
3、可能发生的并发同二维码扫码请求:此处跟web端轮询没有关系,为app端的使用的核心webApi部分。此种情况其实可以考虑接受,因为对于guid令牌的操作只有赋值和置状态。那么在web端轮训到状态改变的时候,就以最后的状态为准。定义状态可以同步推进,但是不能逆向置值
4、如何嵌入到现有的登录流程中中已经描述。
5、前端高PV的二维码状态轮询:此处为web端轮询问题,Ajax部分。出于对二维码轮询可能出现的高PV量,肯定要使用缓存的。考虑也使用Redis作为缓存。


于是我们在核心webApi处需要两个接口:

  1. 扫码访问接口:用于对应guid令牌已经扫码,同时也需要先判断该令牌的状态,不可逆向。直接查询Redis,不存在即认为无效。
  2. 令牌确认登录接口:用于对应guid令牌置为登录状态,同样不可逆向。直接查询Redis,不存在即认为无效。存在的话就将所需的数据同时也存入到Redis中。

接着我们的web端Ajax处也需要两个接口:

  1. 获取二维码接口:IP计数限制访问,使用Redis,10秒40次。生成guid令牌以及对应签名,拼接生成二维码返回,并将生成guid入Redis。
  2. 获取二维码状态接口:先验签,接着使用guid令牌查询Redis。

最后,只有当guid令牌走到最后的登录流程之后,才会正式记录对应guid令牌到数据库中,同时连带状态和所需的所有参数,到这一步的时候,这些数据都应该存在于Redis中,如果不存在,那么就是不合理,应当错误处理。

观察上述,我们可以将guid对于Redis的操作,抽象成一个函数,放入一个业务逻辑类中进行统一维护。当轮询到guid令牌为登录状态时,让前端提交表单,后台接收guid令牌和签名并且优先判断扫码登录,再跳过一些需要跳过的点就成了。

至此为完整的扫码登录轮询方式的流程和设计构想。


结论

早在17年的时候,我从GitHub上看到过一个模拟微信网页版的windowsform项目,拆开来仔细看了看它的登录流程,也是轮询的方式。而且实际在试用的时候,多登陆待扫码就会变得非常卡。但也算是第一次接触到扫码登录方式,算是一种简单暴力的方式。因此高PV的性能问题,是最值得考虑的问题。啊当然,安全第一。


实战

在上述构想和理论的支持下,我们得到了一个基本雏形。真正开发时,还应当考虑一个

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值