En esta ocasión me gustaría compartir con todos ustedes la forma más sencilla en la cual, mediante Django, podemos generar links con fecha de expiración, esto con la finalidad de posteriormente recuperar una contraseña, aunque, realmente podemos utilizar estos links para otras necesidades. 🤔
Afortunadamente Django ya no provee de los módulos y clases necesarias para realizar esta tarea, así que es algo bastante sencillo, veamos.
Crear URL
Los primero que debemos hacer es generar un token. Este token estará asociado a un usuario. De esta forma podemos validar que la petición está siendo realizada por el mismo usuario que generó el token.
Para generar un token nos apoyaremos de la clase PasswordResetTokenGenerator.
Generamos una instancia de la clase PasswordResetTokenGenerator. Una vez hecho esto ejecutamos el método make_token, pasando como argumento el usuario al cual queremos asociar el token.
El método nos retornará un string alfanumérico, el cual tiene una fecha de expiración.
from django.contrib.auth.tokens import PasswordResetTokenGenerator
token_generator = PasswordResetTokenGenerator()
token = token_generator.make_token(user)
Dentro del archivo settings.py mediante la variale PASSWORD_RESET_TIMEOUT_DAYS podemos definir el número mínimo de días para los cuales nuestro link será válido (Por default su valor será 3).
PASSWORD_RESET_TIMEOUT_DAYS = 5
Una vez generado el token podemos colocarlo en el contexto para ser utilizado en nuestro template.
def home(request):
token_generator = PasswordResetTokenGenerator()
token = token_generator.make_token(request.user)
return render(request, 'home.html', {
'token': token,
})
<div class="super-link">
<a href="{% url 'validate_token' %}?token={{token}}">Validar token</a>
</div>
En este caso envió el token como parámetro mediante el query string de la url.
Validar Token
La validación del token es muy sencilla. Nuevamente generamos una instancia de la clase PasswordResetTokenGenerator. Ahora, en esta ocasión, haremos uso del método check_token. Pasamos como argumento el usuario y el token.
is_valid = token_generator.check_token(user, token)
Este método nos retornará valor booleano. Verdadero o Falso dependiendo si el token no a expirado y si le corresponde a dicho usuario.
Apartir de esta validación podemos autorizar o declinar cualquier petición.
Otros usos
Cómo mencione anteriormente, aunque la idea principal de la clase PasswordResetTokenGenerator es generar tokens para autorizar el cambio de contraseña, podemos utilizar estos tokens para diversas tareas, tareas donde es necesario validar la autenticidad del usuario ya que este podría ingresaría a la plataforma por un medio externo, lo más común, mediante el link de un correo electrónico.
Una buena idea, desde mi punto de vista, es almacenar los tokens en nuestra base de datos, con una relación al usuario. De esta forma podríamos validar tokens sin la limitante del tiempo.
is_valid = Token.objects.filter(user=user, token=token).exists()