用户登录的业务流程架构设计

1、目的前端

对用户登录业务流程进行一个梳理,试图从应用层角度来解决业务上曾经遇到的一些坑,提升业务的安全性,可是不可避免,流程上复杂了一些,同时业务处理时间上会有一些损耗。nginx

2、主要流程数据库


一、请求发送前的预处理。在对服务器发起请求以前,经过前端的处理手法,对用户名和密码进行一些处理,好比校验字符串的合理性,对密码进行hash(经常使用的也就是MD5,SHA这些,能够百度一下),对即将提交的数据进行hash来保证网络请求中的合法性,必定程度防止被中间人篡改数据等等。网络请求的API同时也能够采用https来进行辅助。安全

二、进入业务模块前的处理。咱们没有办法知道发送上来的请求是不是有效的请求,可能与重复的数据发送,可能有机器人的行为,也有多是跨过运维的撞库的行为,因此在进入业务模块前,咱们要进行一些预处理,来尽可能减小一些无用的数据,在必定程度上也能够减小一些数据库的压力。服务器

当服务器接收到客户端请求以后,首先会检查来路的ip地址是否存在于黑名单列表中,若是存在的话,这个请求就会被遗弃掉。咱们假定了这个黑名单,用以记录咱们断定为有机器人登录、试图猜想密码、撞库等等异常行为的ip。(事实上在有些团队中,会有负责安全模块的运维同窗或者开发同窗对全局的网络请求进行ip过滤,能够试图基于nginx模块或者其余其余服务器组件进行开发,力求在网络层解决掉这个问题。)网络

由于用户登录的行为咱们没法预知,因此我这里采用的方案是设定了两个机制:第一,在用户登陆页,校验码的出现是随机的,在展现用户登录页面的时候,向服务器发起一次请求,由服务器决定是否在客户端展现校验码;第二,设定重复登录的两个阀值,当单位时间内尝试登录的次数到达第一个阀值时候,咱们认为这是用户正常的行为,可是须要给咱们一个确认,因此咱们在客户端输入数据的时候,强制要求必须有验证码,当到达第二个阀值的时候,咱们才会将用户的ip或用户名放入黑名单,在黑名单中保留一段时间。(由于公网ip是可变的,若是持久放入,可能会影响到真正的用户。在安全要求比较高的场景中,到达阀值的时候,服务提供商会经过各类方式联系用户进行确认,或者短信,或者电话,各有各的招儿吧)架构

若是这个发起请求的ip咱们断定为是有效的,接下来咱们要作的就是对接收到的数据进行一系列校验以确保其合理性。例如完整性校验、字符串校验、特殊字符过滤,是不是replay等等,有必要话,咱们还在对其来路域名进行校验(oauth机制和咱们这个业务不太同样,因此也没有更深刻的考虑),确保这个请求的合法性。运维

三、业务模块的处理加密

进行到这一步,咱们能够断定这个请求是合法的,数据是可用的,接下来业务就相对比较简单了,常规就是根据提交上来的用户名和密码从存储服务器中进行检索。须要注意的是咱们在服务器中存储密码的时候,对密码进行了诸如md5(salt.md5(password))的处理,salt也是可变的,salt或者根据每次登录成功的时间进行变动,或者根据用户信息完整性作的hash,这样即便被拖库,字典造起来也是挺麻烦的一件事情,算是一种对安全上的考虑吧。spa

3、闲话

这个业务架构的设计其实也不算成熟,只是尽可能在业务层减小一些安全问题如撞库、密码猜想、replay,在实际应用中,根据不一样的场景也有不一样的处理方案,如每次登录都会短信通知或发送验证码,ActiveX插件,屏幕键盘等等。

对于replay攻击,见识有限,也不知道有什么特别好的法子,这个业务设计中采用了检查单位时间内表单数据是否提交过,若是提交过的话就不进行任何处理,处理的比较粗放。另外有一种办法就是每一次用户发起登录请求以前,客户端会向服务器请求一个一次性的token,服务器会检查这个token的值和服务器存储的是否一致。

我见过用对称加密的方式来对数据包进行加密,可是这种加密方式的话,客户端代码一旦被反编译,一切都是亮堂堂的,这点不如非对称加密,可是非对称交密又没法保证从服务器获取的私钥必定可信,因此对数据包加密这个方案很差作评估,若是有了解的能够交流一下(saintatgod@gmail.com)。