2012-01-27 187 views
9

我在寻找最好的优雅的方式来锁定一个Django用户帐户多次失败登录尝试失败登录尝试失败后锁定用户

“我试过了什么?”

我对SO上的类似问题看起来没有成功(如果这个问题是一个复制请发表评论,删除这一个)。

目前我正在寻找其他开发者的经验。我不想谈论我为了不回答问题而试过的东西。

作为附加信息,该应用程序没有启用UserProfile(但是,当然,如果它是值得的,我可以启用它)。

+1

锁在外面*用户*基于失败的登录尝试在我看来是设计不当。恶意的第三方可能会故意闯入已知(或预期)帐户,从而锁定实际用户。基于IP等的阻塞(或者可能是地狱阻塞)将是优选的。如果您确实需要更高的安全性,可能是两者的混合,但在尝试更少尝试后出现IP块。 – 2013-09-27 17:53:32

+0

您是不是锁定未经身份验证的用户的帐户?一个小小的不便比妥协的帐户好得多,不是吗? – DylanYoung 2017-06-21 16:37:57

回答

13
+0

不错,谢谢博士!但是这不锁账户(对我来说不是解决方案)。你测试过了吗?有人有经验在真实环境中使用它? – danihp 2012-01-27 13:02:20

+2

@danihp'django-brutebuster'为每个失败的登录尝试创建一个模型实例并在那里记录用户名。所以我认为向这个模型添加'post_save'信号并且在那里锁定用户(一行代码)是相当优雅的。我尝试了django-brutebuster只是为了伐木,而不是在生产(不需要)。 – DrTyrsa 2012-01-27 13:19:00

+0

让我有一段时间来进行审议;) – danihp 2012-01-27 19:22:50

7

我们用django-lockout和它的工作非常出色

+0

感谢分享知识。我已阅读锁定文档,我有一个问题:锁只在缓存级别?有没有办法将用户标记为锁定在数据库中? – danihp 2012-01-27 16:14:14

+0

仅缓存。当白痴试图暴力破解你的系统时,减少负载(没有额外的数据库查询)是有意义的;-) – 2012-01-27 18:40:47

3

一个简单的解决方案是建立在用户配置文件是initialy 0的变量,并增加了每次1用户尝试登录失败。如果此变量达到某个阈值(每次用户尝试登录时都会检查该阈值),则可以暂停用户帐户。当然,当用户成功登录时,变量必须设置为0.

+2

如果你这样做,只需要尝试用他们的用户名登录一对就可以锁定其他人的时代。锁定用户名只与IP结合可能是一个好主意。 – kioopi 2012-09-04 15:30:33

+0

除了@kioopi的提示之外,不需要访问数据库的解决方案可能更可取。 – Max 2016-03-10 10:54:31

1

创建带有两个字段“User”字段/外键和“Timestamp”字段的模型,名为“failed_logins”。

当用户成功登录时,删除该用户的所有“failed_logins”条目。

当用户未成功登录时,使用当前时间戳在该用户的“failed_logins”中创建一个条目。

在每次登录尝试给定用户之前,检查是否密码正确/不正确的:

  • 运行一个查询,删除所有“failed_logins”条目超过15分钟(或W/e时代期)。

  • 运行查询,检查试图登录的用户在failed_logins中的条目数。如果它是5,则终止登录尝试,通知用户他们已经被锁定在他们的帐户之外,并稍后再尝试。

结果: 5次失败登录尝试一段时间后,用户被锁定。

+1

您的解决方案存在问题,即任何人都可以锁定其他用户,因为您的锁是基于帐户的。此外,会有不必要的许多数据库命中。 – Max 2016-03-10 10:55:27

-4

你可以试试这个片断:

<?php 
session_start(); 

$conn = mysql_connect("localhost","root","root"); 
$select = mysql_select_db("Gayathri",$conn) or die("connection error"); 

if(isset($_COOKIE['login'])&&$_COOKIE['login']>=3){ 
echo " you have to wait for sometimes to enable your login"."<br>"; 
} 

if(isset($_POST["username"],$_POST["userpassword"])){ 
    $username = $_POST['username']; 
    $userpassword = $_POST['userpassword']; 

    $query = "SELECT * from userlogin where username='".$username."' and userpassword='".$userpassword."'"; 
    $result = mysql_query($query); 
    $row = mysql_fetch_assoc($result); 

if($row){ 
    echo"login successfull"; 
} 
else{ 
    echo"Invalid password"."<br>"; 
if(isset($_COOKIE['login'])){ 
    $attempts=$_COOKIE['login']+1; 
     }else{ 
    $attempts=1; 
} 
setcookie('login', $attempts, time()+60*60); 
} 

} 
?> 
<form method = "post" action = ""> 
<table border=1> 
<tr> 
    <td>Username:</td> 

    <td><input type="text" name="username" value=""></td> 
</tr> 
<tr> 
    <td>Userpassword:</td> 

    <td><input type="password" name="userpassword" value=""></td> 
</tr> 
<tr> 
    <td colspan="2" align=center><input type="submit" name="submit" value="login"></td> 
</tr> 
</table> 
+1

警告:'mysql_ *'函数[不再支持或维护](https://stackoverflow.com/questions/12859942)。他们[在PHP 5.5.0中弃用](https://wiki.php.net/rfc/mysql_deprecation)和[在PHP 7.0.0中删除](https://php.net/manual/en/function.mysql -connect.php#function.mysql连接重refsynopsisdiv)。强烈建议您迁移到[MySQLi](https://php.net/manual/en/book.mysqli.php)或[PDO_MySQL](https://php.net/manual/en/ref.pdo -mysql.php)。 – Pang 2017-04-20 05:33:52

+1

警告:您的代码容易受到[SQL注入攻击](https://en.wikipedia.org/wiki/SQL_injection)的影响。请阅读[本文](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)了解更多关于如何防止它。 – Pang 2017-04-20 05:33:57