重置java中的密码链接

时间:2016-10-21 10:47:57

标签: java jsp servlets reset-password

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

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

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

  3. 包含指定电子邮件地址并带有重设密码页链接的电子邮件。

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

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

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

  6. 我在我的代码中尝试了这个,但在我的重置密码页面中,我没有得到想要更改密码的用户的电子邮件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;
        }
    }
    

    我的新密码.jsp。

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

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

    你能请求帮我解决这个问题,或者做任何其他选择。

1 个答案:

答案 0 :(得分:2)

我建议你使用JWT令牌 - 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();
  }

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

“您曾要求更改密码。请点击此链接输入新密码”

http://yourapp.com/forgotPassword/qwe213eqwe1231rfqw

然后在加载的页面上,你将从请求中获取令牌,对其进行编码并得到你想要的东西。

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();
  }

如果指定的时间过去,到期将使您的令牌无效。 Salt可以替换为任何类型的String,您可以在JWT文档中阅读详细信息。 这种方法也可以用于registartion confiramtion电子邮件。

P.S。

1)不要使用scriplets(jsp中的java代码),而是使用jstl

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

3)对于像HOST / PASSWORD e.t.c这样的信息。使用属性文件

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