如何在3次尝试后阻止用户的特定时间?



我创建了一个简单的登录servlet,用户输入他的电子邮件和密码,它检查他是否是注册用户,然后它登录他,如果他不是它说登录失败,凭据存储在文本文件中,我不能使用数据库,代码工作完美。现在唯一的问题是,我试图阻止注册用户在3次尝试后的一段特定时间,让我们说30分钟,这是怎么做到的?

文本文件的格式如下:

<<ul>
  • example@mail.com,密码/gh>
  • example2@mail.com, 2
  • 电子邮件和密码用','分隔

    代码:

    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中再添加一个属性,例如:然后,当您检查密码时,也检查登录时间阻塞用户

    在用户会话中创建对象。称之为trackLogOns。当用户第一次尝试登录但失败时,在对象上放置时间戳。另外,在对象上放置一个整数,用于跟踪用户尝试登录和失败登录的次数。每次用户登录时检查该对象的会话。如果该对象存在,但计时器大于120,则删除该会话对象并创建一个新的会话对象,然后继续执行下面的逻辑。如果对象存在且小于120,则将增加计数器并相应地执行操作。例:计数器小于3,只需增加计数器。如果计数器为3或更多,则停止用户。

    如果您正在尝试这样做,而用户尚未登录,则将其放在应用程序级别或上下文作用域的变量中。然后应用程序可以跟踪它。这里有一个链接,可以帮助您了解变量根据其放置位置的范围所能存活的长度。您可能知道,也可能不知道,您可以在页面级别、请求级别、会话级别和应用程序级别将变量放入内存中。应用程序级别可能是使用最少的,但在这种情况下,我认为你需要这个级别。这里有一个链接,可以帮助你更多地了解它。

    https://www.javajee.com/application-request-session-and-page-scopes-in-servlets-and-jsps

    相关内容

    • 没有找到相关文章

    最新更新