java - java中的重置密码链接

标签 java jsp servlets reset-password

我目前正在一个Java项目中实现一个忘记密码的功能。我的方法是,

  1. 用户点击忘记密码链接。

  2. 在忘记密码页面,系统提示用户输入邮箱
    他/她在系统中注册的地址。

  3. 包含给定电子邮件地址和重置密码页面链接的电子邮件。

  4. 用户点击链接,他/她被重定向到一个页面(重置密码) 用户可以在其中输入新密码。

  5. 在“重置密码”页面中,“电子邮件地址”字段会自动填写
    并且无法更改,因为它已禁用。

    然后用户输入他的新密码和与电子邮件相关的字段 数据库中的地址已更新。

我在我的代码中试过了,但在我的重置密码页面中,我没有得到想要更改密码的用户的电子邮件 ID。

MailUtil.java

package com.example.controller;

import java.io.IOException;
import java.security.Security;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import com.example.util.Database;

public class MailUtil {
    private static final String USERNAME = "test@gmail.com";
    private static final String PASSWORD = "test";
    private static final String SUBJECT = "Reset Password link";

    private static final String HOST = "smtp.gmail.com";
    private static final String PORT = "465";

    String email;

    public MailUtil() {
    // TODO Auto-generated constructor stub
    email = this.email;
}

    public boolean sendMail(String to, HttpServletRequest request) throws SQLException, ServletException, IOException{
        Connection conn = Database.getConnection();
        Statement st = conn.createStatement();
        String sql = "select * from login where email = '" + to + "' ";
        ResultSet rs = st.executeQuery(sql);
        String pass = null;
        String firstName = null;
        while(rs.next()){
            pass = rs.getString("pass");
            firstName = rs.getString("firstName");
        }

        if(pass != null){
            setEmailId(to);         
            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
            Properties props = new Properties();
            props.put("mail.smtp.host", HOST);
            props.put("mail.stmp.user", USERNAME);
            //  If you want you use TLS
            //props.put("mail.smtp.auth", "true");

            props.put("mail.smtp.starttls.enable", "true");
            props.put("mail.smtp.password", PASSWORD);
            //  If you want to use SSL
            props.put("mail.smtp.port", PORT);
            props.put("mail.smtp.socketFactory.port", PORT);
            props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.put("mail.smtp.auth", "true");

            Session session = Session.getInstance(props, new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    String username = USERNAME;
                    String password = PASSWORD;
                    return new PasswordAuthentication(username, password);
                }
            });

            String from = USERNAME;
            String subject = SUBJECT;
            MimeMessage msg = new MimeMessage(session);
            try{
                msg.setFrom(new InternetAddress(from));
                InternetAddress addressTo = new InternetAddress(to);
                msg.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
                msg.setSubject(subject);                
                String vmFileContent = "Hello User, <br><br> Please Click <a href='http://192.168.15.159:8080/SampleLogin/new-password.jsp><strong>here</strong></a> to reset your password. <br><br><br> Thanks,<br>ProAmbi Team";

                //  Send the complete message parts
                msg.setContent(vmFileContent,"text/html");
                Transport transport = session.getTransport("smtp");
                transport.send(msg);

                System.out.println("Sent Successfully");
                return true;
            }catch (Exception exc){
                System.out.println(exc);
                return false;
            }
        }else{
            //System.out.println("Email is not registered.");
            request.setAttribute("errorMessage", "User with this email id doesn't exist.");         
            return false;
        }
    }

    public String getEmailID() {
        return email;
    }
    public void setEmailId(String email) {
        this.email = email;
    }
}

还有我的 new-password.jsp。

<%
    MailUtil mail = new MailUtil();
    String email = mail.getEmailID();
    System.out.println("---> "+email);
%>

但我得到的是空值而不是电子邮件 ID。

你能帮我解决这个问题,或者有其他选择吗?

最佳答案

我建议您使用 JWT token - https://jwt.io/

 public String createToken( Email mail )
  {
      Claims claims = Jwts.claims().setSubject( String.valueOf( mail.getId() ) );
        claims.put( "mailId", mail.getId() );
        Date currentTime = new Date();
        currentTime.setTime( currentTime.getTime() + tokenExpiration * 60000 );
        return Jwts.builder()
          .setClaims( claims )
          .setExpiration( currentTime )
          .signWith( SignatureAlgorithm.HS512, salt.getBytes() )
          .compact();
  }

此代码将返回您的 token 字符串表示形式。因此,您将使用此 token 发送电子邮件消息,例如:

“您已请求更改密码。请单击此链接输入新密码”

http://yourapp.com/forgotPassword/qwe213eqwe1231rfqw

然后在加载的页面上,您将从请求中获取 token ,对其进行编码并获取您想要的内容。

public String readMailIdFromToken( String token )
  {
    Jwts.parser().setSigningKey( salt.getBytes() ).parseClaimsJws( token ).getSignature();
    Jws<Claims> parseClaimsJws = Jwts.parser().setSigningKey( salt.getBytes() ).parseClaimsJws( token );        
    return parseClaimsJws.getBody().getSubject();
  }

如果指定的时间过去了,过期将使您的 token 无效。 Salt 可以替换为任何类型的字符串,您可以在 JWT 文档中阅读详细信息。 这种方法也可用于注册确认电子邮件。

附:

1)不要使用scriplets(jsp处的java代码),改用jSTL

2) 不要在 sql 查询中使用字符串连接。这很危险。请改用准备好的语句。

3) 对于诸如 HOST/PASSWORD 等信息使用属性文件

4) 删除将 DB 调用到适当 DAO 的代码。 (你应该阅读 DAO 模式)

5) 根本不要在代码中使用 system.out.println。使用任何类型的记录器。

有用的链接:

https://jstl.java.net/

https://en.wikipedia.org/wiki/SQL_injection

https://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html

https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm

https://en.wikipedia.org/wiki/Multitier_architecture

关于java - java中的重置密码链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40174656/

相关文章:

jsp - JSTL 上的 IntelliJ 警告 "cannot resolve variable"

java - 转换 HTML 上的日期格式

java - Jetty 应用程序抛出 SaxParseException

java - 如何在JSP中检索实体属性(从Servlet传递)

Java文件上传大小检查

tomcat - 如何使用 JavaMail/Servlet 机制创建 ConfirmationURL?

java - SQLException(无效的列索引) - 页面中没有显示结果

Java:实例化 Google Collection 的 HashBiMap

java - 在另一个 Activity 中显示 Double

Grails 2.0 与 Java 7 - 准备好投入生产了吗?