Ссылка для сброса пароля в java

#java #jsp #servlets #reset-password

#java #jsp #сервлеты #сброс пароля

Вопрос:

В настоящее время я внедряю функцию forgot password в проект Java. моя методология заключается,

  1. Пользователь нажимает ссылку «Забыли пароль».

  2. На странице «Забыли пароль» система предлагает пользователю ввести
    адрес электронной почты, который он / она зарегистрировал в системе.

  3. Электронное письмо, которое включает указанный адрес электронной почты со ссылкой на страницу сброса пароля.

  4. Пользователь нажимает на ссылку, и он / она перенаправляется на страницу (сброс пароля), где пользователь может ввести свой новый пароль.

  5. На странице сброса пароля поле «адрес электронной почты» заполняется автоматически
    и его нельзя изменить, поскольку оно отключено.

    Затем пользователь вводит свой новый пароль, и поле, связанное с адресом электронной почты в базе данных, обновляется.

Я пробовал это в своем коде, но на моей странице сброса пароля я не получил идентификатор электронной почты пользователя, который хочет изменить пароль.

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

И мой новый-password.jsp.

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

Но я получил нулевое значение, а не идентификатор электронной почты.

Можете ли вы, пожалуйста, помочь мне решить эту проблему или получить любой другой вариант для этого.

Комментарии:

1. Итак, вы создаете экземпляр нового объекта MailUtil, а затем ожидаете, что он волшебным образом будет содержать идентификатор электронной почты?

2. В вашем классе util нет конструктора по умолчанию, поэтому, по сути, переменная экземпляра равна null. Если вы не задаете значение или не вызываете методы sendMail, я не понимаю, как вы ожидаете получить значение в этом экземпляре

3. @newuserua_ext, я сомневаюсь, что база данных вернет что-то полезное, если to равно нулю 😉 Кстати … посмотрите SQL-инъекцию!

4. @AxelH 😉 я только что увидел точную проблему. вы абсолютно правы. извините за недопонимание

5. Я создал конструктор и внес изменения в свой код. Теперь все в порядке?

Ответ №1:

Я бы посоветовал вам использовать токен 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();
  }
  

По истечении указанного времени ваш токен станет недействительным. Соль может быть заменена любой строкой, вы можете прочитать подробности в документации JWT.
Этот подход также может быть использован для электронных писем с подтверждением регистрации.

p.s.

1) Не используйте скрипты (Java-код в jsp), используйте вместо этого jstl

2) Не используйте конкатенацию строк в sql-запросах. Это опасно. Вместо этого используйте подготовленную инструкцию.

3) Для такой информации, как ХОСТ / ПАРОЛЬ и т.д., используйте файлы свойств

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

Комментарии:

1. Хорошо. Я проверю и дам вам знать.