PHP实现登录失败后账号锁定功能

账号锁定必要性

账号登录过程中最好添加一个安全登录次数限制的机制,防止有人恶意尝试登录。

账号登录失败次数账号锁定机制的必要性在于,它可以防止恶意攻击者通过暴力破解等方式尝试登录系统。如果限制可以执行的失败登录尝试次数,则几乎可以消除此类攻击的有效性。

在实际应用中,可以通过记录用户名和密码验证失败的次数来实现账户锁定机制。具体来说,需要针对每一个用户记录登录失败的次数nLock和锁定账户的到期时间releaseTime。这些信息可以存储在mysql、文件中或redis中等,完全取决于你对你所处的应用架构适用性的判断。

整体实现思路

用户登录失败后,需要记录登录失败日志并进行缓存。在缓存中,存放了登录失败的时间信息,思路是以天为单位进行存储。具体的时间间隔可以根据实际需求进行调整。

在登录过程中,需要先判断用户输入的登录账号是否正确。然后,再对当天登录失败的次数进行判断。如果超过设定的阈值,则直接返回账号被锁定的消息。

实现细节

项目比较老,基于thinkphp3.2的,用文件缓存进行登录状态记录
缓存的数组包含三个属性

$errorLog =array(
	'n' => 2, //登录失败次数
	't' => '2023-06-09', //登录失败日期记录
	't2' =>array('2023-06-08','2023-06-09'), //所有有过登录失败记录的日期
);

登录校验函数

/**
 * 用户登录信息检测
 * $logInfo=array(
 *      'userid'=>'',   //账号
 *      'pwd'=>'',      //密码
 * )
 */
if (!function_exists('checkLogin')) {
    function checkLogin($logInfo = array())
    {
        $userid = $logInfo['userid'] ? trim($logInfo['userid']) : '';
        $pwd = $logInfo['pwd'] ? trim($logInfo['pwd']) : '';

        // 当天登录失败次数超过设置的最大值
        // C('MAX_ERROR_LOGNUM') 是登录失败的阙值,可以根据情况直接换掉或者改成自己的调用方式
        if (getErrorLog($userid) >= C('MAX_ERROR_LOGNUM')) {
            return array('status' => 0, 'info' => '登录失败次数过多,账号被锁定,请联系管理员');
        }
		
		// Login这个地方放登录检验代码,实际情况中可以抽离也可以直接把判断逻辑写在这里
		// 返回值true登录成功,false登录失败
		$loginResult=Login($userid,$pwd);
		
        if (!$loginResult == false) {
            // 登录日志记录
            $num = recordErrorLog($user['userid']);
            if ($num < C('MAX_ERROR_LOGNUM')) {
                return array('status' => 0, 'info' => '账号或密码错误,您还有' . (C('MAX_ERROR_LOGNUM') - $num) . '次机会');
            } else {
                return array('status' => 0, 'info' => '失败次数过多被锁定,请联系管理员');
            }
        }
		// 根据自己情况进行登录状态记录,cookie,session,token等等
		
        return array('status' => 1, 'info' => '登录成功');
    }
}

登录失败日志记录,返回当天失败次数

/**
 * 登录失败日志记录,返回当天失败次数
 */
if (!function_exists('recordErrorLog')) {
    function recordErrorLog($userid)
    {
        $errorLog = F('UserLogError/' . $userid); //用F函数做文件缓存,缓存的名字就是用户的登录账号,简单粗暴。
        $nd = date('Y-m-d');
        if ($errorLog) {
            if ($nd == $errorLog['t']) {
                $errorLog['n']++;
            } else {
                $errorLog['t2'][] = $nd;
                $errorLog = ['n' => 1, 't' => $nd, 't2' => $errorLog['t2']];
            }
        } else {
            $errorLog = ['n' => 1, 't' => $nd, 't2' => [$nd]];
        }
        F('UserLogError/' . $userid, $errorLog);
        return $errorLog['n'];
    }
}

获取账号当天失败次数

/**
 * 获取账号当天失败次数
 */
if (!function_exists('getErrorLog')) {
    function getErrorLog($userid)
    {
        $errorLog = F('UserLogError/' . $userid);
        return ($errorLog['t'] == date('Y-m-d')) ? $errorLog['n'] : 0;
    }
}

小结

上面的代码比较简单,逻辑也不难理解,关键在于把登录状态记录下来,然后根据特定日期和账号进行判断,也可以根据情况实现一个更为复杂的登录失败校验机制的函数,比如限制前5次登录失败后锁定30分钟再登录,如果30分钟后又失败两次,则锁定1小时,半小时后再失败两次则锁定2小时,4小时,8小时…等等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值