Redis接口限流

<?php

/**
 * api 接口限流
 *
 */

class api
{

    public function get_client_ip($type = 0) {
        $type       =  $type ? 1 : 0;
        static $ip  =   NULL;
        if ($ip !== NULL) return $ip[$type];
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos    =   array_search('unknown',$arr);
            if(false !== $pos) unset($arr[$pos]);
            $ip     =   trim($arr[0]);
        }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip     =   $_SERVER['HTTP_CLIENT_IP'];
        }elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip     =   $_SERVER['REMOTE_ADDR'];
        }
        // IP地址合法验证
        $long = ip2long($ip);
        $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
        return $ip[$type];
    }

    public function test()
    {

        //接口时间限流,这种方式可以防止钻时间漏洞无限的访问接口 比如在59秒的时候访问,就钻了空子
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $ip = $this->get_client_ip(true);
        $len = $redis->lLen($ip);
        if($len === 0)
        {
            $redis->lPush($ip,time());
            echo "访问1次<br>";
            $redis->expire($ip,60);
        }else{
            //判断有没有超过1分钟
            $max_time = $redis->lRange($ip,0,0);
            //判断最后一次访问的时间比对是否超过了1分钟
            if((time()- $max_time[0]) < 60){
                if($len> 10){

                    echo '访问超过了限制';
                }else{

                    $redis->lPush($ip,time());
                    echo "访问{$len}次<br>";
                }
            }
        }
    }

}
(new api())->test();

  

原文地址:https://www.cnblogs.com/bing2017/p/13331576.html