tooManyAttempts($account,$pre); true=锁定 false=未锁定 * 2.登录成功,需要重置登录次数:(new ThrottlesUtil())->resetAttempts($account,$pre); * 3.不同体系的账号,可通过设置$pre前缀区分 */ class ThrottlesUtil { private $limitEnabled = true; // 是否开启限流 false=不开启 true=开启 private $limitTime = 1*60; // 间隔时长(s) private $maxAttempts = 5; // 最大登录次数 private $lockTime = 30*60; // 锁定时间(s) private $pre = "<|login|>"; // 前缀避免账号重复 public function __construct($config = []) { if(isset($config['time'])){ $this->limitTime = (int)$config['time']; } if(isset($config['attempts'])){ $this->maxAttempts = (int)$config['attempts']; } if(isset($config['lock'])){ $this->lockTime = (int)$config['lock']; } if(isset($config['enabled'])){ $this->limitEnabled = $config['enabled']; } } /** * 检查是否锁定 * @param $account 账号 * @param string $pre // 缓存前缀,根据前缀区分不同类别账号 * @return boolean false=未锁定 true=已锁定 */ public function tooManyAttempts($account,$pre = 'throttles'){ if(!$this->limitEnabled){ return false; } $key = $pre.$this->pre.$account; //检查是否存在对应lockout缓存 if (cache($key.':lockout')) { return true; } //如果没有的话,attempts($key)返回$key对应的缓存中存储的登录次数 if ($this->attempts($account,$pre) > $this->maxAttempts) { //如果已经超出限制,调用add方法添加对应lockout到缓存 cache($key.':lockout',time() + $this->lockTime, $this->lockTime); //重置当前登录次数 $this->resetAttempts($key); return true; } return false; } /** * 获取登录次数 * @param $account 账号 * @param string $pre 缓存前缀 * @return int */ public function attempts($account,$pre = 'throttles'){ $key = $pre.$this->pre.$account; $times = cache($key); // ["1234567899","1234567892"]存储时间戳 $ndata = []; $count = 0; $curTime = time(); if($times){ $data = json_decode($times,true); if(!empty($data)){ $count = count($data); foreach ($data as $k=>$v){ if($curTime - $v < $this->limitTime){ // 间隔小于时长有效 $ndata[] = $v; } } } } $ndata[] = $curTime; cache($key,json_encode($ndata),$this->limitTime); return $count + 1; } /** * 重置登录次数 * @param $account 账号 * @param string $pre 缓存前缀 */ public function resetAttempts($account,$pre = 'throttles'){ $key = $pre.$this->pre.$account; cache($key,NULL); cache($key.':lockout',NULL); } }