[英]How to block a user for specific time after 3 attempts?
I've created a simple login servlet in which the user enters his email and password and it checks if he's a registered user then it logs him in , if he's not it says login fail,the credentials are stored in a text file , I can't use a database,the code works perfect.我创建了一个简单的登录 servlet,用户在其中输入他的电子邮件和密码,然后检查他是否是注册用户,然后让他登录,如果不是,则说登录失败,凭据存储在文本文件中,我可以不使用数据库,代码运行完美。 Now the only problem is that I'm trying to block a registered user after 3 attempts for a specific period of time , let's say 30 mins , how can that be done ?
现在唯一的问题是我试图在特定时间段内尝试 3 次后阻止注册用户,比如说 30 分钟,这怎么办?
The format of the text file is as follows :文本文件的格式如下:
The email and password are seperated by a ','电子邮件和密码以“,”分隔
CODE :代码 :
import java.io.*;
import java.security.Principal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
//int attempts = 3;
/**
*
*/
private static final long serialVersionUID = -5498866193863633001L;
/**
* HashMap to store all users credentials
*/
private final Map<String, String> credentialsPairs = new HashMap<>
();
@Override
public void init(ServletConfig config) throws ServletException {
String delimiter = ",";
String line = "";
/**
* Credentials file will be there in WEB-INF directory as it
provide secured
* access only.
*/
String credentialFile = "/WEB-INF/accounts.txt";
/**
* Read the file and prepare Map with username as key and
password as value We
* have put this code in init method as it is called once only
that will avoid
* overhead of iterating values from file for each request
*/
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
ServletContext context = config.getServletContext();
try {
/**
* Open stream of file
*/
is = context.getResourceAsStream(credentialFile);
if (is != null) {
/**
* Read the file line by line and store email as a key
and password as value
*/
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
String[] credentials = line.split(delimiter);
// credentials[0] is email and credentials[1] is
password
credentialsPairs.put(credentials[0],
credentials[1]);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
if (isr != null) {
isr.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws IOException, ServletException {
/**
* Get user entered credentials
*/
String userEmail = request.getParameter("email");
String userPassword = request.getParameter("password");
PrintWriter out = response.getWriter();
boolean isValidUser = false;
/**
* Get value from Map for user entered email address.
*/
String password = credentialsPairs.get(userEmail);
/**
* If User with entered email address found then we will get
password for that
* user
*/
if (password != null) {
/**
* Compare password entered by user with one that is
retrieved from file
*/
if (password.equals(userPassword)) {
isValidUser = true;
}
}
HttpSession session = request.getSession();
if (isValidUser) {
//HttpSession session = request.getSession();
session.setAttribute("email", userEmail);
request.getRequestDispatcher("welcome.jsp").include(request,
response);
//response.sendRedirect("welcome.jsp");
}
else {
int loginAttempt;
if (session.getAttribute("loginCount") == null)
{
session.setAttribute("loginCount", 0);
loginAttempt = 0;
}
else
{
loginAttempt = (Integer)
session.getAttribute("loginCount");
}
//this is 3 attempt counting from 0,1,2
if (loginAttempt >= 2 )
{
long lastAccessedTime =
session.getLastAccessedTime();
Date date = new Date();
long currentTime = date.getTime();
long timeDiff = currentTime - lastAccessedTime;
// 20 minutes in milliseconds
if (timeDiff >= 1200000)
{
//invalidate user session, so they can try
again
session.invalidate();
}
else
{
// Error message
session.setAttribute("message","You have
exceeded the 3 failed login attempt. Please try loggin
in in 20 minutes.");
}
}
else
{
loginAttempt++;
int allowLogin = 3-loginAttempt;
session.setAttribute("message","loginAttempt=
"+loginAttempt+". Invalid username or password. You have
"+allowLogin+" attempts remaining. Please try again! <br>Not a
registered cusomer? Please <a
href=\"register.jsp\">register</a>!");
}
session.setAttribute("loginCount",loginAttempt);
}
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher("index.jsp");
dispatcher.forward(request, response);
}
public void destroy() {
/**
* Free up the map
*/
credentialsPairs.clear();
}
}
您应该在credentialPairs中再添加一个属性,例如 ,然后在检查密码时还要检查登录时间以阻止用户
Create an object in the users session.在用户会话中创建一个对象。 Call it trackLogOns.
称之为 trackLogOns。 Put a timestamp when on the object the first time the user attempts to log in but fails.
在用户第一次尝试登录但失败时在对象上放置时间戳。 Also put a integer on the object for tracking the times the user tries and fails to log on.
还要在对象上放置一个整数,用于跟踪用户尝试登录和登录失败的次数。 Check the session for the object every time the user logs on.
每次用户登录时检查对象的会话。 If the object exists but the timer is longer than 120, delete the session object and create a new one and proceed with the logic below.
如果对象存在但计时器超过120,则删除会话对象并创建一个新对象,然后继续执行以下逻辑。 If the object is exists and it's less than 120 you'll increment the counter and act accordingly.
如果对象存在并且它小于 120,您将增加计数器并相应地采取行动。 Eg The counter is less than 3 just increment the counter.
例如计数器小于 3 只是增加计数器。 If the counter is 3 or more, stop the user.
如果计数器为 3 或更多,则停止用户。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.