Breaking

Post Top Ad

Your Ad Spot

viernes, 14 de junio de 2019

Spring de Seguridad : funcionalidad de contraseña olvidada

Introducción

Internet se está volviendo más y más orientado a los servicios, a medida que más empresas y compañías crean ofertas que se pueden proporcionar o acceder en línea. Esto requiere que los usuarios creen muchas cuentas en diferentes plataformas para los servicios que obtienen en línea. Estos servicios van desde compras en línea hasta servicios basados ​​en suscripciones, como ofertas de música y entretenimiento y también servicios educativos que incluyen cursos y paquetes de tutoriales.
Los usuarios de Internet terminan creando muchas cuentas diferentes para diferentes plataformas, y no se recomienda usar la misma contraseña en todos los servicios. Esto trae consigo la carga de recordar múltiples contraseñas diferentes para múltiples cuentas y, desafortunadamente, algunas se filtran y son olvidadas porque, después de todo, somos humanos.
Olvidar las contraseñas es un problema real al que se enfrentan los usuarios y, como desarrolladores de sistemas y plataformas, podemos facilitarles la gestión de sus contraseñas ofreciéndoles una funcionalidad que les permita restablecer sus contraseñas de forma segura en caso de que las olviden. Esto ayudará a mejorar la retención de clientes en nuestra plataforma, ya que pueden estar seguros de que, en caso de que perdieran su contraseña, no habrán perdido su cuenta.
En esta publicación, exploraremos cómo Spring Security nos ayuda no solo a proteger nuestras aplicaciones basadas en Spring, sino también a nuestros usuarios a recuperar sus contraseñas perdidas de una manera fácil y segura.

Asegurar aplicaciones web con Spring Security

Spring Security es un marco que es fácil de ampliar y personalizar y se centra en la prestación de servicios de autenticación y control de acceso para aplicaciones basadas en Spring. Maneja la autenticación y la autorización y también ayuda a proteger las aplicaciones Java contra vulnerabilidades de seguridad comunes y ataques como la fijación de sesiones, el clickjacking y la falsificación de solicitudes entre sitios, entre otros.
Spring Security también se puede usar para simplificar las funciones de administración de cuentas en la aplicación Java Enterprise a través de características tales como la provisión del marco de autorización OAuth2 para permitir a los usuarios utilizar plataformas de terceros para identificarse en nuestras aplicaciones Java.
Esto se implementa más comúnmente a través de Social Login, donde podemos usar nuestras cuentas en plataformas como Facebook, Twitter, Google y Github para acceder e identificarnos en otras plataformas.
OpenID es un protocolo de autenticación promovido por OpenID Foundation que es descentralizado y estándar, que se puede usar para iniciar sesión en varios sitios web sin tener que crear nuevas contraseñas. OpenID es compatible con Spring Security y puede usarse para facilitar el registro y el acceso a nuestras aplicaciones Java para nuestros usuarios finales.
En el caso de organizaciones que utilizan el protocolo LDAP (Lightweight Directory Access Protocol) como servicio de autenticación y depósito central de información del usuario, Spring Security proporciona la funcionalidad para integrar LDAP en su aplicación basada en Spring.
Esto permitirá a los miembros actuales de las organizaciones acceder de forma segura a las nuevas aplicaciones con sus credenciales existentes sin tener que crear un conjunto de credenciales totalmente nuevo.

Gestión de contraseñas en Spring Security

Hemos visto un subconjunto de la funcionalidad que ofrece Spring Security y hace aún más por nuestras contraseñas. Spring Security toma las credenciales de un usuario y las convierte en un token que se pasa a una AuthenticationManagerinstancia para validar las credenciales. En caso de que la contraseña sea incorrecta, Spring Security proporcionará comentarios sobre el error y el proceso no pasará de ese punto.
Después de la validación, se establece un contexto de seguridad y ahora el usuario se considera autenticado. El contexto de seguridad también define la función del usuario en el sistema y se puede usar para determinar el nivel de acceso permitido, ya sea como administrador o como usuario normal.
Spring Security utiliza una PasswordEncoderinterfaz para codificar o transformar contraseñas para facilitar el almacenamiento seguro de las credenciales. Se supone que esta contraseña codificada es de una manera y el proceso de verificación implica comparar la contraseña que el usuario ha proporcionado con la que está almacenada y, si coinciden, los detalles son correctos.
Con el fin de mejorar la seguridad de las contraseñas de los usuarios, Spring Security permite a los desarrolladores utilizar funciones de una sola vía (o hashes) para codificar contraseñas como Bcrypt , Argon2 , Scrypt y PBKDF2 . Estas funciones requieren muchos recursos, pero su propósito es ser unidireccional y hacer que sea más difícil para los atacantes descifrar y extraer las credenciales de los usuarios.
Si desea leer más sobre este tema, puede consultar el artículo Codificación de contraseña con Spring Security .
Las prácticas de almacenamiento de contraseñas seguirán cambiando con el tiempo para mejorar la seguridad de los métodos actuales y es por esta razón que Spring Security introdujo la DelegatingPasswordEncoderinterfaz en la versión 5.0+.
Asegura que la codificación de la contraseña utiliza los métodos recomendados actualmente para el almacenamiento de la contraseña y permite la actualización de las funciones de codificación en el futuro. También nos permite usar diferentes funciones de codificación para diferentes contraseñas y esto se puede distinguir utilizando un identificador prefijado en la contraseña codificada. Por ejemplo, si usamos Bcrypt para codificar nuestras contraseñas, la salida sería, por ejemplo:
{bcrypt}$2a$12$rBvYrRneJjT/pmXakMbBg.vA1jUCpEMPE5z2tY3/4kyFw.KoiZA6C
En ausencia del prefijo de identificación, se utiliza una función de codificación predeterminada.
Así es como Spring maneja las contraseñas y la seguridad en general, pero ¿qué sucede cuando nuestros usuarios olvidan sus credenciales?

Envío de correos electrónicos en Spring Boot

Los sistemas y plataformas utilizan los correos electrónicos para identificar a los usuarios y también para enviarles comunicaciones y promociones. Esto hace que las direcciones de correo electrónico sean importantes para la identidad de un usuario de Internet y que no tenga tantas cuentas de correo electrónico para uso personal. Esto significa que la cuenta de correo electrónico de un usuario es fácil y fácilmente accesible para ellos, ya que la usan con frecuencia. Por lo tanto, el correo electrónico es una de las mejores vías para ayudar a los usuarios a recuperar sus contraseñas.
Para permitir a nuestros usuarios restablecer sus contraseñas, nuestra aplicación basada en Spring debe poder enviar correos electrónicos a los usuarios. A través de estos correos electrónicos, podemos proporcionar tokens o enlaces o instrucciones a nuestros usuarios que detallan cómo pueden recuperar sus cuentas.
Java proporciona la biblioteca javax.mail , también conocida como JavaMail, que podemos usar para enviar correos electrónicos a nuestros usuarios cada vez que olvidan sus contraseñas. La JavaMailbiblioteca nos permite redactar y enviar correos electrónicos a través de varios protocolos como SMTP (Protocolo simple de transferencia de correo), POP (Protocolo de oficina postal) o IMAP(Protocolo de acceso a mensajes de Internet).
Nos permite enviar correos electrónicos de texto sin formato, así como mensajes que contienen HTML, lo que hace que nuestros correos electrónicos sean atractivos y llamativos. Incluso podemos enviar correos electrónicos con archivos adjuntos cuando usamos la JavaMailbiblioteca.
Si está interesado en obtener más información sobre el envío de correos electrónicos en Java , lo tenemos cubierto.
Otras bibliotecas que puedes usar para enviar correos electrónicos en Java incluyen:
  • Simple Mail , que está construido sobreJavaMail
  • Commons Email , que también está construido sobreJavaMail
  • JavaMailSender , que es una biblioteca de utilidades proporcionada por Spring Framework.

Implementación

Ahora reunamos todo lo anterior en un proyecto y ayudemos a nuestros usuarios a recuperar sus contraseñas con facilidad.
El objetivo principal de este artículo era proporcionar orientación sobre la funcionalidad de restablecer la contraseña. Antes de que podamos restablecer las contraseñas, debemos permitir a los usuarios registrarse, confirmar sus cuentas por correo electrónico y permitirles iniciar sesión en sus cuentas confirmadas.
El artículo Spring Security: Registro de verificación de correo electrónico cubre el registro de usuario y la confirmación de cuentas a través de un token enviado al correo electrónico del usuario. Con el espíritu de mantener este artículo centrado en la funcionalidad de restablecimiento de contraseña, vamos a bifurcar y ampliar este proyecto en GitHub que se basa en ese artículo y agregaremos nuestra nueva funcionalidad que incluye el inicio de sesión y la funcionalidad de restablecer la contraseña.

Resumen

El proyecto utiliza el marco de Spring junto con Spring Security junto con Thymeleaf como el motor de plantillas del lado del servidor. Hibernate se utiliza para interactuar con una base de datos MySQL para guardar los detalles de los usuarios.
Un usuario accede al sistema y se le solicita inmediatamente que se registre al proporcionar sus detalles, incluidos sus nombres, la dirección de correo electrónico para la verificación y una contraseña. En las siguientes secciones, continuaremos desde allí y agregaremos primero la funcionalidad de inicio de sesión, luego agregaremos la funcionalidad de restablecer contraseña para ayudar a nuestros usuarios a restablecer sus contraseñas.

Cambios y Adiciones

Hay algunas cosas que cambiaremos en este proyecto y las resaltaré a medida que avancemos. Primero, actualizaremos la versión Spring de 1.5.42.1.4.RELEASEen nuestro pom.xmlTambién actualizaremos la versión del conector MySQL a la versión 8.0.13para que el proyecto se ejecute sin problemas con la versión Spring actualizada.
Si bien la versión anterior aún funciona, la actualización de las dependencias garantiza que podamos aprovechar la nueva funcionalidad que se introdujo en la versión posterior. Además, algunos problemas que podríamos enfrentar se eliminarán mediante el uso de paquetes actualizados.
Necesitaremos configurar nuestra base de datos local y actualizar el applications.propertiesarchivo para adaptarlo a nuestra nueva configuración. También necesitaremos actualizar la configuración de correo electrónico para facilitar el envío de correos electrónicos:
# add these new properties
spring.mail.transport.protocol=smtp  
spring.mail.from.email=<your-email-goes-here>

# modify these properties with your credentials
spring.mail.username=<your-email-goes-here>  
spring.mail.password=<password-goes-here>

# update our database configuration
spring.datasource.url=jdbc:mysql://localhost:3306/demodb?allowPublicKeyRetrieval=true&useSSL=false  
spring.datasource.username=<database-username>  
spring.datasource.password=<database-password>  
Con esta configuración modificada, podemos ejecutar el proyecto y registrarnos como nuevos usuarios. El correo electrónico proporcionado application.propertiesaparecerá en el remitente del correo electrónico que contiene el token de confirmación.

Funcionalidad de inicio de sesión

Podemos registrar y confirmar nuestra cuenta por correo electrónico en este momento. Antes de que podamos restablecer nuestras contraseñas, deberíamos poder iniciar sesión y, cuando olvidemos nuestra contraseña, deberíamos poder restablecerla. Para implementar la funcionalidad de inicio de sesión, comenzaremos creando las plantillas, luego la vista en el controlador.
Nuestra página de inicio de sesión tendrá campos para el correo electrónico y la contraseña, y una sección oculta para mostrar los mensajes cuando sea necesario. Tales mensajes pueden incluir notificar al usuario cuando proporcionan credenciales no válidas o cuando el usuario no existe en el sistema. También crearemos una plantilla adicional que se mostrará en el inicio de sesión exitoso, que servirá como nuestra página de inicio.
En nuestra carpeta de plantillas, agregamos la página de inicio de sesión:
<!DOCTYPE html>  
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">  
    <head> <title>Login</title> </head>
    <body>
        <center> <span th:text="${message}"></span> <br/> </center>
        <center>
            <form action="#" th:action="@{/login}" th:object="${user}" method="post">
                <table>
                    <tr>
                        <td><label for="emailId">Email</label></td>
                        <td><input th:field="*{emailId}" type="text" name="emailId"></input></td>
                    </tr>
                    <tr>
                        <td><label for="password">Password</label></td>
                        <td><input th:field="*{password}" type="password" name="password"></input></td>
                    </tr>
                    <tr>
                        <td><input type="reset" value="Clear"/></td>
                        <td><input type="submit" value="Submit"></input></td>
                    </tr>
                </table>
            </form>

            <a href="/forgot-password">Forgot Password?</a>
        </center>
    </body>
</html>  
Este es un formulario que toma una dirección de correo electrónico y una contraseña y envía esa información a nuestro controlador en el /loginpunto final para su verificación. También hay un Forgot Password?enlace, que implementaremos más adelante.
Después de iniciar sesión correctamente, notificamos al usuario y lo redirigimos a la página de inicio, que en nuestro caso simplemente será successLogin.html:
<!DOCTYPE html>  
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"  
  xmlns:th="http://www.thymeleaf.org">
    <head> <title>Login Success</title> </head>
    <body>
        <center> <span th:text="${message}"></span> </center>
    </body>
</html>  
Permítanos extender nuestro UserAccountControllerque se encuentra en la controllercarpeta para incluir la funcionalidad de inicio de sesión.
Primero, importaremos la BCryptPasswordEncoderclase para codificar nuestras contraseñas e instanciarlas para cifrar y comparar nuestras contraseñas. Inicialmente, el proyecto guardó contraseñas sin procesar en la base de datos, lo modificaremos para que las contraseñas estén cifradas cuando el usuario se esté registrando, ya que guardar las contraseñas sin procesar no es una buena práctica.
Para la funcionalidad de inicio de sesión, implementaremos una función para mostrar la página con el formulario de inicio de sesión, y otra función para recibir las credenciales, verificarlas y notificar cualquier problema o llevar al usuario a la siguiente página si es necesario. Si el correo electrónico proporcionado no existe en nuestra base de datos, también notificaremos al usuario.
BCryptPasswordEncoderproporciona la matches(rawPassword, encodedPassword)función que nos ayuda a comparar la contraseña proporcionada con la que tenemos en los registros. Usamos este método en lugar de codificar la contraseña sin procesar y comparar, ya que cada vez se usa un saltdiferente y la comparación directa fallaría todo el tiempo.
Primero agregamos la nueva importación:
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;  
Y luego incluir estos cambios:
    // Instantiate our encoder
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12);

    // Right before saving the user on registration, we encode the password
    user.setPassword(encoder.encode(user.getPassword()));
    userRepository.save(user);

    // Function to display login page
    @RequestMapping(value="/login", method=RequestMethod.GET)
    public ModelAndView displayLogin(ModelAndView modelAndView, User user) {
        modelAndView.addObject("user", user);
        modelAndView.setViewName("login");
        return modelAndView;
    }

    // Function to handle the login process
    @RequestMapping(value="/login", method=RequestMethod.POST)
    public ModelAndView loginUser(ModelAndView modelAndView, User user) {
        User existingUser = userRepository.findByEmailIdIgnoreCase(user.getEmailId());
        if (existingUser != null) {
            // Use encoder.matches to compare raw password with encrypted password

            if (encoder.matches(user.getPassword(), existingUser.getPassword())){
                // Successfully logged in
                modelAndView.addObject("message", "Successfully logged in!");
                modelAndView.setViewName("successLogin");
            } else {
                // Wrong password
                modelAndView.addObject("message", "Incorrect password. Try again.");
                modelAndView.setViewName("login");
            }
        } else {
            modelAndView.addObject("message", "The email provided does not exist!");
            modelAndView.setViewName("login");
        }
        return modelAndView;
    }
Cuando ejecutamos nuestro proyecto, esta es la página resultante cuando navegamos hasta el /loginpunto final:
página de inicio de sesión
Si las credenciales son incorrectas, se muestra un mensaje que contiene el error en la parte superior del formulario y, si son válidas, el usuario es redirigido a una página que muestra un mensaje de éxito.
Ahora nuestro usuario puede iniciar sesión con sus credenciales, pero ¿qué sucede cuando las olvida? El Forgot Password?enlace viene al rescate.

Olvidé la funcionalidad de la contraseña

Cuando un usuario olvida su contraseña, puede solicitar que se restablezca haciendo clic en el Forgot Password?enlace. Se le pedirá al usuario que proporcione la dirección de correo electrónico con la que se registró y se generará un token y se enviará a la dirección de correo electrónico como parte del enlace.
Una vez que el usuario haga clic en el enlace de restablecimiento, validaremos el token y redirigiremos al usuario a una página donde puedan ingresar una nueva contraseña para su cuenta. Ahora guardaremos esta nueva contraseña una vez que hayamos confirmado que el usuario tiene acceso a la dirección de correo electrónico que proporcionó. Ahora podrán iniciar sesión con las credenciales actualizadas.
Crearemos la plantilla de contraseña olvidada donde el usuario ingresará su dirección de correo electrónico a través de la forgotPassword.htmlplantilla:
<!DOCTYPE html>  
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"  
 xmlns:th="http://www.thymeleaf.org">
    <head> <title>Forgot Password</title> </head>
    <body>
        <center>
            <form action="#" th:action="@{/forgot-password}" th:object="${user}" method="post">
                <table>
                    <tr>
                        <td><label for="emailId">Email</label></td>
                        <td><input th:field="*{emailId}" type="text" name="emailId"></input></td>
                    </tr>
                    <tr>
                        <td><input type="reset" value="Clear"/></td>
                        <td><input type="submit" value="Reset Password"></input></td>
                    </tr>
                </table>
            </form>
        </center>
    </body>
</html>  
Crearemos una successForgotPassword.htmlplantilla adicional para mostrar el mensaje de éxito cuando la contraseña se haya restablecido con éxito y esté presente en la base de código completa vinculada a continuación.
Con la plantilla en su lugar, actualicemos nuestra UserAccountControllerpara manejar esta nueva funcionalidad. Tendremos una función para mostrar el formulario y otra para recibir el correo electrónico, crear un token y enviar un correo electrónico al usuario con el enlace para restablecer la contraseña del usuario.
Las adiciones a nuestro controlador incluyen:
    // Display the form
    @RequestMapping(value="/forgot-password", method=RequestMethod.GET)
    public ModelAndView displayResetPassword(ModelAndView modelAndView, User user) {
        modelAndView.addObject("user", user);
        modelAndView.setViewName("forgotPassword");
        return modelAndView;
    }

    // Receive the address and send an email
    @RequestMapping(value="/forgot-password", method=RequestMethod.POST)
    public ModelAndView forgotUserPassword(ModelAndView modelAndView, User user) {
        User existingUser = userRepository.findByEmailIdIgnoreCase(user.getEmailId());
        if (existingUser != null) {
            // Create token
            ConfirmationToken confirmationToken = new ConfirmationToken(existingUser);

            // Save it
            confirmationTokenRepository.save(confirmationToken);

            // Create the email
            SimpleMailMessage mailMessage = new SimpleMailMessage();
            mailMessage.setTo(existingUser.getEmailId());
            mailMessage.setSubject("Complete Password Reset!");
            mailMessage.setFrom("test-email@gmail.com");
            mailMessage.setText("To complete the password reset process, please click here: "
              + "http://localhost:8082/confirm-reset?token="+confirmationToken.getConfirmationToken());

            // Send the email
            emailSenderService.sendEmail(mailMessage);

            modelAndView.addObject("message", "Request to reset password received. Check your inbox for the reset link.");
            modelAndView.setViewName("successForgotPassword");

        } else {
            modelAndView.addObject("message", "This email address does not exist!");
            modelAndView.setViewName("error");
        }
        return modelAndView;
    }
Ahora podemos empaquetar y ejecutar nuestro proyecto nuevamente usando el mvn spring-boot:runcomando. Cuando hacemos clic en el Forgot Password?enlace, podemos ver un formulario con un campo de correo electrónico. Cuando completamos nuestra dirección de correo electrónico registrada, recibimos el siguiente correo electrónico:
correo electrónico
Hasta ahora, hemos podido recibir una solicitud de restablecimiento de contraseña y hemos enviado un correo electrónico al usuario con un enlace para restablecer su contraseña.
Para implementar la siguiente parte de la funcionalidad de restablecimiento de contraseña, necesitaremos crear una plantilla que reciba la nueva contraseña del usuario. Se parecerá a la página de inicio de sesión, la única diferencia importante es que el campo de correo electrónico será de solo lectura.
La nueva plantilla resetPassword:
<!DOCTYPE html>  
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"  
 xmlns:th="http://www.thymeleaf.org">
    <head> <title>Reset Password</title> </head>
    <body>
        <center>
            <h2>Enter new password:</h2>
            <form action="#" th:action="@{/reset-password}" th:object="${user}" method="post">
                <table>
                    <tr>
                        <td><label for="emailId">Email</label></td>
                        <td><input th:field="*{emailId}" type="text" name="emailId" readonly></input></td>
                    </tr>
                    <tr>
                        <td><label for="password">Password</label></td>
                        <td><input th:field="*{password}" type="password" name="password"></input></td>
                    </tr>
                    <tr>
                        <td><input type="reset" value="Clear"/></td>
                        <td><input type="submit" value="Submit"></input></td>
                    </tr>
                </table>
            </form>
        </center>
    </body>
</html>  
Rellenaremos previamente la dirección de correo electrónico del usuario en un campo de solo lectura y luego permitiremos que el usuario ingrese su nueva contraseña.
Dos nuevos puntos finales serán introducidos en este punto:
  • /confirm-reset: maneja la verificación del token y, en caso de éxito, redirigirá al usuario al siguiente punto final
  • /reset-password: muestra el formulario de arriba, recibe las nuevas credenciales y las actualiza en la base de datos
Agreguemos estos nuevos puntos finales en nuestro controlador de la siguiente manera:
    // Endpoint to confirm the token
    @RequestMapping(value="/confirm-reset", method= {RequestMethod.GET, RequestMethod.POST})
    public ModelAndView validateResetToken(ModelAndView modelAndView, @RequestParam("token")String confirmationToken) {
        ConfirmationToken token = confirmationTokenRepository.findByConfirmationToken(confirmationToken);

        if (token != null) {
            User user = userRepository.findByEmailIdIgnoreCase(token.getUser().getEmailId());
            user.setEnabled(true);
            userRepository.save(user);
            modelAndView.addObject("user", user);
            modelAndView.addObject("emailId", user.getEmailId());
            modelAndView.setViewName("resetPassword");
        } else {
            modelAndView.addObject("message", "The link is invalid or broken!");
            modelAndView.setViewName("error");
        }
        return modelAndView;
    }

    // Endpoint to update a user's password
    @RequestMapping(value = "/reset-password", method = RequestMethod.POST)
    public ModelAndView resetUserPassword(ModelAndView modelAndView, User user) {
        if (user.getEmailId() != null) {
            // Use email to find user
            User tokenUser = userRepository.findByEmailIdIgnoreCase(user.getEmailId());
            tokenUser.setPassword(encoder.encode(user.getPassword()));
            userRepository.save(tokenUser);
            modelAndView.addObject("message", "Password successfully reset. You can now log in with the new credentials.");
            modelAndView.setViewName("successResetPassword");
        } else {
            modelAndView.addObject("message","The link is invalid or broken!");
            modelAndView.setViewName("error");
        }
        return modelAndView;
    }
Con estos nuevos cambios, podemos ejecutar el proyecto y hacer clic en el enlace que vino en el correo electrónico de restablecimiento de contraseña que se envió anteriormente. El resultado es:
restablecer la contraseña
Cuando ingresamos nuestra nueva contraseña, recibimos un mensaje de éxito. Nuestra contraseña se ha actualizado y podemos probar esta nueva contraseña navegando a la página de inicio de sesión e iniciando sesión con las nuevas credenciales.
¡Funciona! Nuestros usuarios ahora pueden restablecer sus contraseñas olvidadas a través de enlaces enviados a su dirección de correo electrónico desde nuestra aplicación web Spring Boot.

Conclusión

Hemos aprendido de las diversas formas en que Spring Security puede proporcionar servicios de autenticación y control de acceso para ayudarnos a proteger nuestras aplicaciones basadas en Spring de una manera fácilmente extensible y personalizable.
También hemos entendido cómo Spring Security maneja las contraseñas de nuestros usuarios a través de varios algoritmos para codificar y almacenar de forma segura la contraseña de manera que sea indescifrable para un atacante. Resaltamos brevemente cómo podemos enviar correos electrónicos en Spring y, en nuestro caso, utilizamos este conocimiento para enviar correos electrónicos para confirmar las cuentas de nuestros usuarios cuando se registran y también para recuperar su cuenta. Esta funcionalidad de correo electrónico también se puede utilizar al enviar notificaciones de inicio de sesión o al marcar actividades sospechosas en las cuentas de los usuarios.
Finalmente, extendimos un proyecto de registro de correo electrónico de Spring agregando la funcionalidad de inicio de sesión y restablecimiento de la contraseña para ayudar a nuestros usuarios en caso de que no puedan recordar sus credenciales.
El código base completo y final de este proyecto está disponible aquí en Github .

No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

Post Top Ad

Your Ad Spot

Páginas