登录失败次数限制(原生php代码实现)

思路
1.需要一个表(user_login_info)负责记录用户登录的信息,不管登录成功还是失败都记录。并且登陆失败还是成功需要能够区分开来。

2.每次登陆时,都先从user_login_info表查询最近30分钟内(这里假设密码错误次数达到5次后,禁用用户30分钟)有没有相关密码错误的记录,然后统计一下记录总条数是否达到设定的错误次数。

3.如果在相同IP下,同一个用户,在30分钟内密码错误次数达到设定的错误次数,就不让用户登录了。
具体代码与及表设计
user_login_info表

   CREATE TABLE `user_login_info` (
       `id` int(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT  NOT NULL,
       `uid` int(10) UNSIGNED NOT NULL,
       `ipaddr` int(10) UNSIGNED NOT NULL COMMENT '用户登陆IP',
       `logintime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 
       COMMENT '用户登陆时间',
       `pass_wrong_time_status` tinyint(10) UNSIGNED NOT NULL COMMENT '登陆密码错误状态' 
       COMMENT '0 正确 2错误'
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 /**
     * 检查用户最近$min分钟密码错误次数
     * $uid 用户ID
     * $lock_time  锁定时间
     * $wTIme 错误次数
     * @return 错误次数超过返回false,其他返回错误次数,提示用户
     */
    public function checkPassWrongTime($uid, $lock_time=30, $wTime=3)
    {
        try{
            $time = time();
            $prevTime = time() - $lock_time*60;
            //用户所在登录ip
            $ip = ip2long( $_SERVER['REMOTE_ADDR'] );
            $loginErrorCounts = UserLoginInfo::where(['uid'=>$uid,'pass_wrong_time_status'=>2,'ipaddr'=>$ip])
                ->where('UNIX_TIMESTAMP(logintime)','between',$prevTime,$time)
                ->count();
            if($loginErrorCounts >= $wTime){
                throw new Exception(100075);
            }
        }catch (Exception $exception){
            throw new Exception($exception->getMessage());
        }
    }
//记录密码输出信息 type 2登陆错误,0正常
    public static function recordPassWrongTime($uid,$type)
    {
        //ip2long()函数可以将IP地址转换成数字
        $ip = ip2long($_SERVER['REMOTE_ADDR']);
        $data['ipaddr'] = $ip;
        $data['uid'] = $uid;
        $data['pass_wrong_time_status'] = $type;
        $data['logintime'] = date("Y-m-d H:i:s");
        UserLoginInfo::create($data);
    }

优化版:限制ip多次登陆

 /**
     * 检查用户最近$min分钟密码错误次数
     * $uid 用户ID
     * $lock_time  锁定时间
     * $wTIme 错误次数
     * @return 错误次数超过返回false,其他返回错误次数,提示用户
     */
    public function checkPassWrongTime($uid, $lock_time=30, $wTime=5)
    {
        try{
            $time = time();
            $prevTime = time() - $lock_time*60;
            //用户所在登录ip
            $ip =  $_SERVER['REMOTE_ADDR'];
            $loginErrorCountsByIp = Db::name('user_login_info')->where(['pass_wrong_time_status'=>2,'ipaddr'=>$ip])
                ->where('logintime','between',[$prevTime,$time])
                ->count();
            if($loginErrorCountsByIp >= $wTime){
                throw new Exception('访问受限制');
            }
            $loginErrorCounts = Db::name('user_login_info')->where(['uid'=>$uid,'pass_wrong_time_status'=>2,'ipaddr'=>$ip])
                ->where('logintime','between',[$prevTime,$time])
                ->count();
            if($loginErrorCounts >= $wTime){
                throw new Exception('登录错误次数超出限制,请过三十分钟重新登录');
            }
        }catch (Exception $exception){
            $this->error($exception->getMessage());
        }
    }
    //记录密码输出信息 type 2登陆错误,0正常
    public  function recordPassWrongTime($uid,$type)
    {
        //ip2long()函数可以将IP地址转换成数字
        $ip =$_SERVER['REMOTE_ADDR'];
        $data['ipaddr'] = $ip;
        $data['uid'] = $uid;
        $data['pass_wrong_time_status'] = $type;
        $data['logintime'] = time();
        Db::name('user_login_info')->insert($data);
    }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值