java - 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. 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 ?
The format of the text file is as follows :
- example@mail.com,password
- example2@mail.com,password2
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();
}
}
解决方案
您应该在 credentialsPairs 中再添加一个属性,例如,然后在检查密码时还要检查登录时间以阻止用户
推荐阅读
- javascript - 如何格式化 nivo 行中 x 轴的值?
- sql - Postgresql split_part 获取最后一个索引位置
- websphere-liberty - 相对命名空间 - SOAP 调用 - Liberty
- javascript - 如何使用 lodash 对数字字符串字段进行排序
- c# - 使用内部等待的方法处理表单
- azure - 为什么我的应用注册设置需要管理员同意?
- terraform - 使用 Terraform 的 ECS 和 Application Load Balancer 临时端口
- javascript - Discord javascript bot 创建错误“未定义消息”
- javascript - 如何在promise中设置react hook的值?
- python - 预期为“Py_ssize_t”但得到“长”