6

我用一个小小的开放设计题,干掉了40%的面试候选人

 3 years ago
source link: https://my.oschina.net/jiagoujingjin/blog/4982099
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.

f4dd6a05-9c8f-498e-914a-79e074fe54f7.png

去年团队招聘需求比较大,本人参与了近百次的面试工作。今天来跟大家聊聊,面试候选人过程中,一个常见的开放类设计题目的解题思路,以及候选人的理解设计误区分析。

64eb3e43-4b8c-43a5-95e8-c73e6a710e53.png

话不多说,咱们直接奔主题。

问题其实很简单,是一个手机绑定验证的场景。大概描述就是:

用户手机验证场景下,正常会给用户手机号码发验证短信,用户收到验证短信后填写验证码进行提交,完成验证。

第一个问题

正常短信发送逻辑没有问题,但由于短信资源宝贵,防止被恶意攻击,你有什么好的控制策略呢?

在面试交流过程中,收集到的答案无外乎这样几种,收集整理归类如下:

1. 发送时间间隔

设置同一个号码重复发送的时间间隔(前端置灰,后端设置间隔锁),一般设置为60-120秒。该手段可以在一定程度上防止短信接口被恶意攻击,且对用户体验没有什么伤害。但是不能防止更换手机号方式进行攻击,防护等级较低。

2. 获取次数限制

是指限制某个手机号在某个时间段内获取短信验证码次数的上限值。

采用这种策略时在产品设计过程中,有几点需要注意:

1)上限值的定义。需要根据业务真实的情况,甚至需要考虑到将来业务的发展定一个合适的上限值,避免因用户无法收到短信验证码而带来的投诉。

2)锁定时间段的定义。需要根据业务情况进行定义,可以是6小时,可以是12小时、24小时。

3. IP限制

设置单个IP地址某个时间段内最大的发送量。

该手段可很好的预防单一IP地址的攻击,但是也有很明显的缺点:

1)对于经常变更IP地址进行攻击的攻击者,该手段几乎没有很好的效果。

2)IP的限制经常会造成误伤。如在一些使用统一无线网的场所,很多用户连接着同一个无线网,这个IP地址就容易很快达到上限,从而造成连接该无线网的用户都无法正常的收到验证码。

4. 图形验证码

在发送短信验证码之前,必须通过通过图形验证码的校验。

这种手段相对来说可以防止某些攻击,因此也是目前非常普遍的短信防攻击机制。但是在使用过程中涉及到用户体验问题,不能简单粗暴地套用这一策略。

以下两个点值得仔细考虑:

1)是不是每次获取短信验证码之前都需要用户输入图形验证码,一般来说这样做会极大地影响用户体验,虽然是相对安全,但是用户用着不爽了。

2)可以给一个安全范围。

结合手机号限制、IP限制来考虑,比如同一个手机号当天第3次获取短信验证码的时候,出现图形验证码;比如同一个IP地址当天获取验证码次数超过100次后,出现图形验证码。

5. 加解密控制

通过对传向服务器各项参数进行加密,到了服务器再进行解密,同时用token作为唯一性识别验证,在后端对token进行验证,验证通过才能正常将短信发送。该手段可以在保证用户体验的情况下,可以有效防止某些攻击,因此也是目前比较常见的短信防攻击机制。

同时也有很明显的缺点:

1)使用的加解密算法可能会被识别,需要考虑使用识别难度较大的加解密算法。

2)在算法不被识别的情况下可以有效防止报文攻击,但是无法防止浏览器模拟机式攻击。

第二个问题

假如需要对用户请求发短信接口进行限制,具体策略针对同一用户手机号发送短信验证码,10分钟之内请求超3次则需要图形验证码(即先验证图形验证码通过后再发送短信),你会如何设计并实现呢?

好多同学听完题目后,就会就能很快给出一个解题思路,大概描述如下:

92d53d1d-719f-46f5-bf85-253b6f83f7e0.png

实现思路:利用Redis KV存储方式,用手机号作为Key,Value记录短信成功发送次数,同时设置过期时间10min。

假设发送时间如下所示:

56c7a71d-d5b7-478c-8650-a57e594706ae.png

到10.07时候申请发送,判断value的值已为3,发送失败,需要出现图形验证码进行补充验证。

上面的逻辑看似没有问题,其实它将时间自然切片处理了。

d2719943-abe2-4e33-9c2d-da8ef2707b7f.png

1)按照上面的逻辑,在10.00-10.10这个时间段周期内:10.01、10.07、10.08 分别发送三次短信,是OK的。

2)接着在10.10-10.20这个时间段周期内:10.11、10.13、10.15 也是可以成功发送短信的。

这样就出现了问题:

在10.07、10.08、10.11、10.13、10.15 这十分钟时间里,竟然发送了5条短信!

这样就绕过了发送短信超3次需要图形验证码验证的操作,这显然是不合理的。

其实好多候选人看到10min 和次数限制后,就陷入到了思维定势中去了。

那有什么好的解题思路么?

在此,针对此种问题,提供一种解题思路:

利用Redis List数据格式;Key:send_msg_phone Value:请求时间戳。

直接上实现代码吧:

/** * Redis 单位时间内请求次数限制 * User: 架构精进之路 * Date: 2021/03/11 * Time: 10:23 */
$key = 'send_msg_xxx'; //xxx 指具体手机号$listLen = lLen($key);if($listLen < 3){    // 直接将当前时间戳插入List尾部    Lpush($key, now());} else {    $index0Time = Lindex($key);    if((当前时间 - $index0Time) < 10min){        // 触发10min内请求大于3次,提醒,“请求过多,请稍后再试。”        echo "请求过多,请稍后再试。";        exit;    } else {        // 将当前时间戳插入List尾部        // 取出List头部首元素        Lpush($key, now());        Ltrim($key, 0, 9);    }}

随着目前安全问题造成的影响日趋严重,Web 安全控制对于研发人员来说是一个非常重要的课题。

通过上面的问题,想要了解到大家对安全防控的认知有哪些,有什么好的处理方案,以及对不同方案之间的优劣比较有怎样的认知。

有了好的方案之后,那如何设计实现呢?在具体落地过程中,还有什么需要补充和注意的事项呢?

......

一系列连续的开放性问题走下来,你就能很好的判断候选人在这部分的能力水平了。

9f52a924-0622-4a76-a81d-b6bec486e870.jpg

对于此类问题,此文抛砖引玉,相信大家还有其他解题思路,欢迎留言区一起探讨交流~

- END -


作者:架构精进之路,专注软件架构研究,技术学习与个人成长,关注并私信我回复“01”,送你一份程序员成长进阶大礼包,欢迎勾搭。


往期热文推荐:


c9971fe4-6cd4-45fb-a667-fbe57f109d29.png

「技术架构精进」专注架构研究,技术分享

Thanks for reading!

本文分享自微信公众号 - 架构精进之路(jiagou_jingjin)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK