2012-01-27 89 views
9

Tôi đang tìm kiếm cách thanh lịch nhất để khóa tài khoản người dùng Django sau nhiều lần đăng nhập thất bại.Khóa người dùng sau quá nhiều lần đăng nhập không thành công

"Tôi đã thử gì?":

Tôi đã xem xét không thành công cho các câu hỏi tương tự trên SO (Nếu câu hỏi này là một câu hỏi vui lòng, hãy đăng nhận xét để xóa câu hỏi này).

Hiện tại tôi đang tìm kiếm trải nghiệm của các nhà phát triển khác. Tôi không muốn nói về những gì tôi đã cố gắng để không điều kiện các câu trả lời.

Khi thông tin bổ sung, ứng dụng chưa bật UserProfile (nhưng, tất nhiên, tôi có thể bật ứng dụng nếu nó đáng giá).

+1

Khóa ra * người dùng * dựa trên nỗ lực đăng nhập thất bại là thiết kế nghèo theo ý kiến ​​của tôi. Một bên thứ ba độc hại có thể cố ý vứt bỏ các tài khoản đã biết (hoặc dự kiến), khóa người dùng thực sự. Chặn (hoặc có thể chặn địa ngục) dựa trên IP hoặc tương tự sẽ được ưu tiên. Nếu bạn muốn bảo mật cao hơn, có lẽ là sự kết hợp của hai, nhưng nơi khối IP xảy ra sau ít lần thử hơn. –

+0

Không phải là toàn bộ điểm mà bạn đang khóa tài khoản đối với người dùng chưa được xác thực? Một sự bất tiện nhỏ là tốt hơn nhiều so với một tài khoản bị xâm phạm, phải không? – DylanYoung

Trả lời

13
+0

đẹp, cảm ơn bác sĩ!Nhưng điều này không khóa tài khoản (không phải là một giải pháp cho tôi). Bạn đã thử nghiệm bất kỳ của cả hai? Ai đó có kinh nghiệm sử dụng nó trong một môi trường thực tế? – danihp

+2

@danihp 'django-brutebuster' tạo một phiên bản mẫu cho mọi lần đăng nhập thất bại và ghi lại tên người dùng ở đó. Vì vậy, tôi nghĩ rằng nó khá thanh lịch để thêm tín hiệu 'post_save' vào mô hình này, và khóa người dùng ở đó (một dòng mã). Tôi đã thử django-brutebuster chỉ để đăng nhập, nhưng không phải trong sản xuất (không cần phải). – DrTyrsa

+0

hãy để tôi một chút thời gian để cân nhắc;) – danihp

7

Chúng tôi sử dụng django-lockout và nó làm việc rất tốt

+0

Nhờ chia sẻ bí quyết. Tôi đã đọc tài liệu lockoup và tôi có một câu hỏi: khóa chỉ ở cấp bộ nhớ cache? Có cách nào để đánh dấu người dùng là bị khóa trong cơ sở dữ liệu không? – danihp

+0

Chỉ bộ nhớ cache. Nó làm cho tinh thần để giảm tải (không có truy vấn DB thêm) khi morons đang cố gắng bruteforce hệ thống của bạn ;-) –

3

Một giải pháp đơn giản sẽ tạo ra một biến trong Hồ sơ người dùng đó là khởi tạo là 0 và tăng 1 mỗi lần người dùng không cố gắng đăng nhập. Nếu biến này đạt đến một ngưỡng nhất định (được kiểm tra mỗi khi người dùng cố gắng đăng nhập), tài khoản người dùng có thể bị tạm ngưng. Tất nhiên khi người dùng đăng nhập thành công, biến phải được đặt về 0.

+2

Nếu bạn làm theo cách này nó sẽ có thể khóa người khác bằng cách chỉ cần cố gắng đăng nhập với tên người dùng của họ một vài thời gian. Khóa tên người dùng chỉ kết hợp với IP có lẽ là một ý tưởng hay. – kioopi

+0

Bên cạnh gợi ý của @kioopi, một giải pháp không cần phải nhấn vào cơ sở dữ liệu có lẽ là thích hợp hơn. – Max

1

Tạo mô hình có tên là "failed_logins" với hai trường, trường "Người dùng"/khóa ngoài và trường "Dấu thời gian".

Khi người dùng đăng nhập thành công, hãy xóa tất cả các mục nhập "failed_logins" cho người dùng đó.

Khi người dùng đăng nhập không thành công, hãy tạo mục nhập trong "failed_logins" cho người dùng đó bằng dấu thời gian hiện tại.

Trên mỗi nỗ lực đăng nhập cho một người dùng nhất định, trước khi kiểm tra để xem nếu mật khẩu là đúng/sai:

  • chạy một truy vấn xóa tất cả "failed_logins" mục già hơn 15 phút (hoặc w thời gian/e giai đoạn).

  • chạy truy vấn kiểm tra số lượng mục nhập trong failed_logins cho người dùng đang cố đăng nhập. Nếu đó là 5, hãy xóa nỗ lực đăng nhập, thông báo cho người dùng rằng họ đã bị khóa tài khoản của họ và thử lại sau một thời gian ngắn.

Kết quả: Người dùng bị khóa sau 5 lần đăng nhập không thành công trong một thời gian ngắn.

+1

Giải pháp của bạn có vấn đề, rằng bất kỳ ai cũng có thể khóa người dùng khác, bởi vì khóa của bạn dựa trên tài khoản. Hơn nữa sẽ có nhiều lần truy cập cơ sở dữ liệu không cần thiết. – Max

-4

Bạn có thể thử đoạn này:

<?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

Cảnh báo: Các chức năng 'mysql_ *' là [không còn được hỗ trợ hoặc duy trì] (https://stackoverflow.com/questions/12859942). Họ đã được [không được chấp nhận trong PHP 5.5.0] (https://wiki.php.net/rfc/mysql_deprecation) và [gỡ bỏ trong PHP 7.0.0] (https://php.net/manual/en/function.mysql -connect.php # function.mysql-connect-refsynopsisdiv). Bạn được khuyến khích chuyển sang [MySQLi] (https://php.net/manual/en/book.mysqli.php) hoặc [PDO_MySQL] (https://php.net/manual/en/ref.pdo -mysql.php). – Pang

+1

Cảnh báo: Mã của bạn dễ bị tấn công [tấn công SQL injection] (https://en.wikipedia.org/wiki/SQL_injection). Vui lòng đọc [bài đăng này] (https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) để tìm hiểu thêm về cách ngăn chặn nó. – Pang

Các vấn đề liên quan