您的位置:首页 > 数据库 > Redis

PHP中Yii2框架用redis实现限制接口访问次数

2017-09-28 11:19 1541 查看
很多情况下,我们需要对一些接口限制访问次数,用于防止恶意请求。

这时候,我们可以写一个工具类的方法,用于限制请求次数。

/** 尝试次数限制
* @param $key
* @param $prefix //前缀,用于跟key组合存redis
* @param $timeLimit //限制的时间
* @param $tryTimes //限制的次数
*/
public static function tryLimit($key, $prefix, $timeLimit, $tryTimes)
{
$times = Yii::$app->redis->get($key . $prefix) ?: 0;
if ($times >= $tryTimes) { //一小时只能获取$tryTimes次
echo '亲,操作太频繁,请过' . round($timeLimit / 3600, 2) . '小时后再来!';
} else {
Yii::$app->redis->setex($key . $prefix, $timeLimit, $times + 1);
}
}

/** 尝试次数限制
* 通过ip进行限制
*/
public static function controllerLimit($params, $funcName)
{
foreach ($params as $v) {
if ($v['funciton'] == $funcName) {
self::tryLimit($v['funciton'], (string)Yii::$app->request->userIP, $v['time_limit'], $v['try_times']);
}
}
}


tryLimit()是一个公用的方法,传入的$prefix参数可以是请求用户的IP,也可以是别的关键参数,例如用户登入时传的手机号,邮箱等等。

当然用户请求的会是具体的接口,比如现在有个需求,想让用户在一小时最多只能登入20次。

public function init()
{
if (in_array(Yii::$app->requestedRoute, [
'login/alipay', 'login/wei-xin', 'login/mobile'
])) {
self::controllerLimit([
[
'funciton' => 'login/alipay',
'time_limit' => 3600,
'try_times' => 20,
], [
'funciton' => 'login/wei-xin',
'time_limit' => 3600,
'try_times' => 20,
], [
'funciton' => 'login/mobile',
'time_limit' => 3600,
'try_times' => 20,
]
], Yii::$app->requestedRoute);//限制IP访问接口次数(一小时访问只能访问20次)
}
}
/** 支付宝登入 */
public function actionAlipay()
{
}
/** 微信登入 */
public function actionWeiXin()
{
}
/** 手机号登入 */
public function actionMobile()
{
}


上面这段代码,可以做到限制的目的,相对于在每个具体的方法里面使用tryLimit()方法,倒不如初始化的时候限制来的优雅。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php redis yii 框架 class