您的位置:首页 > 运维架构 > 网站架构

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

2015-12-01 17:40 435 查看
摘要: 对用户登陆业务流程进行一个梳理,试图从应用层角度来解决业务上曾经遇到的一些坑,提高业务的安全性,但是不可避免,流程上复杂了一些,同时业务处理时间上会有一些损耗。

一、目的

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

二、主要流程



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

2、进入业务模块前的处理。我们没有办法知道发送上来的请求是否是有效的请求,可能与重复的数据发送,可能有机器人的行为,也有可能是跨过运维的撞库的行为,所以在进入业务模块前,我们要进行一些预处理,来尽量减少一些无用的数据,在一定程度上也可以减少一些数据库的压力。

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

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

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

3、业务模块的处理

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

三、闲话

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

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

我见过用对称加密的方式来对数据包进行加密,但是这种加密方式的话,客户端代码一旦被反编译,一切都是亮堂堂的,这点不如非对称加密,但是非对称交密又无法保证从服务器获取的私钥一定可信,所以对数据包加密这个方案不好做评估,如果有了解的可以交流一下(saintatgod@gmail.com)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息