#java #jsp #servlets #reset-password
#java #jsp #сервлеты #сброс пароля
Вопрос:
В настоящее время я внедряю функцию forgot password в проект Java. моя методология заключается,
-
Пользователь нажимает ссылку «Забыли пароль».
-
На странице «Забыли пароль» система предлагает пользователю ввести
адрес электронной почты, который он / она зарегистрировал в системе. -
Электронное письмо, которое включает указанный адрес электронной почты со ссылкой на страницу сброса пароля.
-
Пользователь нажимает на ссылку, и он / она перенаправляется на страницу (сброс пароля), где пользователь может ввести свой новый пароль.
-
На странице сброса пароля поле «адрес электронной почты» заполняется автоматически
и его нельзя изменить, поскольку оно отключено.Затем пользователь вводит свой новый пароль, и поле, связанное с адресом электронной почты в базе данных, обновляется.
Я пробовал это в своем коде, но на моей странице сброса пароля я не получил идентификатор электронной почты пользователя, который хочет изменить пароль.
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://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
Комментарии:
1. Хорошо. Я проверю и дам вам знать.