【问题标题】:Automatic token expire after 5 minutes Java5分钟后自动令牌过期Java
【发布时间】:2020-05-26 16:01:07
【问题描述】:

我正在尝试创建一种更安全的方法来在没有任何框架的情况下使用 Java Web 和 HSQLDB 重置忘记的密码。

我创建了一个表单,用户可以在其中插入他的电子邮件,如果电子邮件在数据库中,它将自动发送一封带有密码重置链接的电子邮件。该链接有一个特定的令牌,当每个用户单击接收电子邮件的按钮时,该令牌会为他们创建。这个令牌被插入到数据库中,同时也是它创建时的时间戳。

如果令牌达到 5 分钟的限制时间,我会尝试从数据库中删除令牌,但它不起作用。 有没有办法做到这一点?谢谢。

我的表:

CREATE TABLE user (
id bigint identity NOT NULL,
username varchar(50) NOT NULL,
email varchar(50) NOT NULL,
password varchar(50) NOT NULL,
attempts int DEFAULT 3,
state varchar(50) DEFAULT 'Active’,
reset_token uuid,
time_token TIMESTAMP,
PRIMARY KEY (id)
);

令牌生成器:

public class TokenGenerator {
    public static String UniqueToken() {
    String token = UUID.randomUUID().toString();
    return token;

}}

我的班级ForgotPasswordHandler.java:


public class ForgotPasswordHandler {
    private static PreparedStatement ps = null;
    private static ResultSet rs = null;
    private static Connection con = DBConnectionManager.getConnection();

    //Creates a token for the user when it clicks on submit for forgot password
        public static void CreateToken (String email) {


            try
              { 

              if (con == null){
                 System.out.println("Failed connection");

              }else{
                  String token = TokenGenerator.UniqueToken();


                PreparedStatement ps = con.prepareStatement(
                  "UPDATE user SET reset_token = ?, time_token = ? WHERE email = ?");

                ps.setString(1,token);
                ps.setTimestamp(2,new Timestamp(new Date().getTime()));
                ps.setString(3, email);

                ps.executeUpdate();
                ps.close();


              }}
            catch (Exception e) {
                 e.printStackTrace(System.out);

              }
        }


       //This is where I'm having trouble to delete the actual token after 5 minutes.

        public static void DeleteToken() {

            try
              { 

              if (con == null){
                 System.out.println("Failed Connection");

              }else{



                PreparedStatement ps = con.prepareStatement(
                  "UPDATE user SET reset_token = NULL WHERE time_token < NOW() - INTERVAL 5 MINUTE");


                ps.executeUpdate();
                ps.close();


              }}
            catch (Exception e) {
                 e.printStackTrace(System.out);

              }

        }

}

我的 Servlet ForgotPassword.java:

    public class ForgotPassword extends HttpServlet {
        private static final long serialVersionUID = 1L;
        private String host;
        private String port;
        private String email;
        private String name;
        private String pass;

        public void init() {
            // reads SMTP server setting from web.xml file
            ServletContext context = getServletContext();
            host = context.getInitParameter("host");
            port = context.getInitParameter("port");
            email = context.getInitParameter("email");
            name = context.getInitParameter("name");
            pass = context.getInitParameter("pass");
        }



        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                //verify if emails exists in db

                String email = request.getParameter("email");

                if(!UserReset.EmailCheck(email)) {

                    String message = "This email isn't in our database";
                    request.setAttribute("message", message);
                    request.getRequestDispatcher("reset.jsp").forward(request, response);   

                } else {
                    String recipient = request.getParameter("email");
                    String subject = "Your Password has been reset";



                    String token = TokenGenerator.UniqueToken();
                    ForgotPasswordHandler.CreateToken(email);
                    ForgotPasswordHandler.DeleteToken();    

                    String url = "http://localhost:8080/login/reset-password.jsp?token=" + token;
                    UserReset.RefreshState(email);

                    //Builds email message and sends it
                    String content = "Hello, please change your password in this link:" + url;
                    content += "\nObrigado!";

                    String message = "";

                    try {
                        EmailSender.sendEmail(host, port, email, name, pass,
                                recipient, subject, content);
                        message = "Please verify your email.";
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        message = "Ops, an error occured: " + ex.getMessage();
                    } finally {
                        request.setAttribute("message", message);
                        request.getRequestDispatcher("reset.jsp").forward(request, response);
                    }

                }

    }

}

【问题讨论】:

  • 有什么问题?
  • @Erwin 我写的 5 分钟后更新的方法没有任何作用
  • 你在 5 分钟后更新它并且用户请求再次重置密码,或者...?
  • 什么是“更安全”?你是什​​么意思“不起作用”?日志文件/堆栈跟踪在哪里?

标签: java token hsqldb


【解决方案1】:

您可能不应该主动删除令牌。只需记录下token的时间,然后当有新的查询进来的时候,获取创建时间,检查是否在5分钟以内。

【讨论】:

  • 我该怎么做呢?因为我确实记录了创建令牌的时间,但是我如何检查它是否在5分钟之内?
  • 在您的登录检查令牌中,也选择时间,例如Select token from w where id=x and token=y and token_create_time &lt; z,其中 z 是当前时间减去 5 分钟
猜你喜欢
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-01
  • 2019-12-07
  • 2017-06-13
  • 1970-01-01
相关资源
最近更新 更多