最近一个活动被人搞,主要频繁提交,把这边的一个表塞了很多恶心数据。
场景为:
手机访问,输入身份证相关信息,接口1~3秒,其它活动相关信息。再提交。
处理方式:
主要加了些验证,如图形和session限制。
因为是手机访问,所以同ip是很有可能的情况,只能做一个大阀值处理,但是阀值不好控制,多了没效果,少了,真实手机用户有问题。所以异常ip需要先确认是不是一些运营商的服务器这些要查查。不是就可以直接封了。再加个简单的session校验,说实在,没啥用。不过一般人是通过电脑才来黑,如果通过运营商(就是手机热点)。同时用代理也有一定几率伪造终端ip,暂时都没有啥太好的方式感觉。
贴代码(yii版本):
<?php
/**
* 特别注意:
* 服务器上和本地的类是不同的。本地服务器因为链接问题,所以直接进行reture处理。
* @author caihaibin
*
*/
class SubmitTools {
static function model() {
return new SubmitTools ();
}
/**
* 防重复提交校验
*
* @param string $key
* 特殊项目,自己提供当前用户唯一标志。如:活动id+用户手机号码 (必要时,活动链接也可以)
* @param boolean $debug_write_log
* 当为true时,所有通过和不通过都写入到日志
* @return boolean 指定时间内的第一次提交,为true,重复提交会抛出异常
*/
static function record($key = '', $debug_write_log = false) {
if (empty ( $key )) {
$key = 'submit_' . Yii::app ()->session->getSessionID ();
}
$result = Yii::app ()->tmpcache->get ( $key );
if ($result) {
if ($debug_write_log)
write_log ( 'mult_submit_error', $key );
throw new Exception ( '当前用户,10秒内只能提交一次' );
}
Yii::app ()->tmpcache->add ( $key, '1', 10 );
if ($debug_write_log)
write_log ( 'mult_submit', $key );
return true;
}
}
上面这个版本是结合php-redis的版本
因为场景里有个情况叫身份校验延迟,这种情况下,验证码校验后更新了数据,但是在会话结束前是不会写到session的数据源里的。所以用redis,记录提交的标志。不提供的情况下就是session_id,还可以自己拼标志,比如身份证号。
多提供个yii的:
Yii::app ()->tmpcache->add ( $key, '1', 10 );
源码说明:
/**
* Stores a value identified by a key into cache if the cache does not contain this key.
* This is the implementation of the method declared in the parent class.
*
* @param string $key the key identifying the value to be cached
* @param string $value the value to be cached
* @param integer $expire the number of seconds in which the cached value will expire. 0 means never expire.
* @return boolean true if the value is successfully stored into cache, false otherwise
*/
protected function addValue($key,$value,$expire)
{
if ($expire == 0)
return (bool)$this->executeCommand('SETNX',array($key,$value));
if($this->executeCommand('SETNX',array($key,$value)))
{
$this->executeCommand('EXPIRE',array($key,$expire));
return true;
}
else
return false;
}
储存标记是原来有的,则不进行覆盖。同时yii其它cache方式如file也有相应处理。