page contents

PHP设计短信验证码防刷机制,你能想出多少种方案?

大部分产品都会涉及到短信验证码的使用界面,尤其是手机产品,短信验证码几乎已经成为所有手机产品的标准。因此,防止短信被刷成了每个产品经理和开发人员关心的问题。 没有体验过短信被刷问题...

大部分产品都会涉及到短信验证码的使用界面,尤其是手机产品,短信验证码几乎已经成为所有手机产品的标准。因此,防止短信被刷成了每个产品经理和开发人员关心的问题。

没有体验过短信被刷问题的产品经理可能不会太注意这个问题。在这篇文章中,我将简要介绍黑色工具的短信轰炸机。短信轰炸机是一个软件,使用书面程序刷短信大量。它可以自动批量提交手机号码,模拟IP等方式刷短信。

因此,在设计需要使用短信验证码的产品时,必须制定限制规则,避免短信被闪现。

在PC时代,大多数平台通过图形验证码的形式降低了被机器刷过的风险。最典型的例子是12306“奇妙的验证码”。然而,在移动互联网时代,用户体验非常重要,有时使用图形验证码会对用户体验产生一定的影响。那么,除了图形验证码的方式外,还有什么方法可以解决短信被刷的问题呢?


提供了几种方案仅供参考:思路都在,代码就容易实现咯


1、时间限制:60秒后才能再次发送

从发送验证码开始,前端(客户端)将执行60秒的倒计时。 在这一分钟之内,用户无法提交多个发送信息的请求。 尽管通常使用此方法,但它不是很有用。 技术更好的人可以绕过此限制,直接发送短信验证码。

代码如下:

//检查是否相隔60秒后发送
$limitKey = "mobile_sms_send_limit:" . $mobile;
$smsSendLimit = Yii::app()->redis->get($limitKey);
if ($smsSendLimit) {
$this->_end(1, '60秒后才能重新发送短信验证码!');
}


2、手机号限制:同一个手机号,24小时之内不能够超过5条

使用相同的手机号码注册或发送SMS验证码的其他操作时,系统可以限制手机号码。 例如,在24小时内只能发送5个短信验证码。 如果超出限制,则会报告错误(例如:忙,请稍后再试)。 但是,这只能避免手动刷短信。 对于使用不同手机号码批量发送短信的计算机,此方法无助。

代码如下:

/检查发送次数
$key = "mobile_sms_send_times:" . $mobile . ":" . date("YmdHis");
$smsSendTimes = Yii::app()->redis->get($key);
if (empty($smsSendTimes)) {
$smsSendTimes = 0;
} else if ($smsSendTimes >= 5) {
$this->_end(1, '每个手机号每天最多能发5条短信!');
}


3、短信验证码限制:30分钟之内发送同一个验证码

网上还有另一种方法:30分钟内,发送的所有短信验证码都是相同的验证码。 第一次请求SMS界面,然后缓存短信验证码结果。 如果您在30分钟内再次请求,您将直接返回缓存的内容。 对于此方法,尚不清楚短信接口提供程序是否会为发送缓存的信息收取费用。 如果您有兴趣,可以了解一下。

部分代码如下

<?php

//这里判断是否存在短信缓存
if(Cache::get('codeCache') != null){
//短信30分钟内存在,则继续发同一条短信给用户
$code = Cache::get('codeCache');
//接下来把code发给用户的业务操作
。。。

}else{
//接收短信验证码
$code = $this->smsTplTrait() //假如这里作为接收到短信"562334"
//将接收到的code存在Cache里30分钟
Cache::put('codeCache', $code, 30);

}

?>


4、前后端校验:提交Token参数校验

这种方式比较少人说到,个人觉得可以这种方法值得一试。前端(客户端)在请求发送短信的时候,同时向服务端提交一个Token参数,服务端对这个Token参数进行校验,校验通过之后,再向请求发送短信的接口向用户手机发送短信。


5、唯一性限制:微信产品,限制同一个微信ID用户的请求数量

如果是微信的产品的话,可以通过微信ID来进行识别,然后对同一个微信ID的用户限制,24小时之内最多只能够发送10条短信。


6、产品流程限制:分步骤进行

例如,在注册的短信验证码使用情况下,我们将注册步骤分为两个步骤。 用户输入手机号码并设置密码后,下一步是进入验证码验证步骤。


7、图形验证码限制:图形验证通过后再请求接口

图形验证码前后台交互流程比较简单,主要分为以下三步:

  • 客户端请求到页面的同时,向服务端发起请求,服务端生成验证码将验证码字符,存入到session中以备客户端的校验。与此同时,服务端将生成的验证码图形给到前端;
  • 前端获取到验证码图形,渲染展示到页面。用户识别图形验证码后,提交验证码的字符到服务端;
  • 服务端接收到验证码校验的请求,将接收到的字符与session中存储的验证码字符进行比对,并将比对结果返回到前端。
PHP设计短信验证码防刷机制,你能想出多少种方案?

前端部分代码

<div class="form-group col-lg-6"> 
<label for="id" class="col-sm-4 control-label"> 验证码: </label>
<div class="col-sm-8">
<input type="text" id="code" name="code" class="form-control" style="width:250px;" />
<img id="imgObj" alt="验证码" src="/article/getValidateCode" οnclick="changeImg()" />
<a href="#" οnclick="changeImg()">换一张</a>
</div>

后端部分代码

<?php
/**
* 这里是判断获取的code与存在session的code是否一致,一致则进入下一步,发短信验证码
* 1 首先要处理的是前端要获取从后端响应过去的code,所以php后端要有生成验证码的代码,生成session,并且响应给前端用
* 2 前端获取到code后与session做比较
*/

public function checkCode(Request $request)
{
$code = $request->input('code');
if($code == SESSION['getCode']){
//这里就是通过验证码后,接下来发送短信的业务逻辑,根据自己的业务需要把
$consignee_content = $this->smsTplTrait('consignee_order', 1); //查找短信模板
$consignee_content = sprintf($consignee_content);
$this->sendSmsTrait($consignee_content, '', 1); //发送短信
}else{
response(['status'=>'0' ,'message' => '验证码有误,无法发送短信']);
}
}


?>


8、IP及Cookie限制:限制相同的IP/Cookie信息最大数量

使用Cookie或IP,您可以轻松识别同一用户,然后限制同一用户(例如,您最多只能在24小时内发送20条短信)。 但是,可以清理Cookie,可以模拟IP,并且IP在局域网中也可以具有相同的IP。 因此,使用此方法时,应考虑具体情况。

代码如下:

//检查IP发送次数
$keyIp = "mobileIp_sms_send_times:" . PublicFunHelper::getIP() . ":" . date("YmdHis");
$smsIpSendTimes = Yii::app()->redis->get($keyIp);
if (empty($smsIpSendTimes)) {
$smsIpSendTimes = 0;
} else if ($smsIpSendTimes >= 20) {
$this->_end(1, '您获取短信验证过于频繁,请稍后再试!');
}


9、短信预警机制,做好出问题之后的防护

以上的方法可能无法完全防止短信被刷。 因此,我们还应该对短信进行良好的预警机制,即当短信使用量达到一定数量时,向管理员发送预警消息,管理员可以立即对短信界面进行监控和保护。

  • 发表于 2020-02-06 17:26
  • 阅读 ( 802 )
  • 分类:PHP开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章