Django - Login con Email y Contraseña | Programador Web Valencia

Django - Login con Email y Contraseña

3 minutos

Django

Por defecto Django solo nos deja identificarnos con el nombre de usuario (username) y la contraseña (password) . A priori práctico. Pero la realidad es peculiar. El ser humano no es una base de datos, por lo que tiende a olvidar. Necesitamos un sistema para que el usuario medio no tenga que memorizar mucho. Sin dejar de lado la contraseña… Habría que realizar un sistema para no solo recuperar la contraseña en caso de perdida, sino para además obtener el nombre de usuario. Y claro, con algún tipo de pregunta de seguridad… que no se olvide la respuesta… que se envíe un Email con un token… ¡Paren las rotativas! ¡KISS! (Keep it Simple, Stupid!). La simplicidad es nuestro objetivo. Cambiemos el nombre de usuario por el email. No es la solución, pero si un principio.

Django 4.x en adelante

Paso 1

Creamos un nuevo documento Python con el nombre backends.py dentro de la aplicación (a la altura de views.py y models.py). Y pegamos el contenido:

from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import User

class EmailAuthBackend(BaseBackend):
    """
    Email Authentication Backend

    Allows a user to sign in using an email/password pair, then check
    a username/password pair if email failed
    """

    def authenticate(self, request, username=None, password=None):
        """ Authenticate a user based on email address as the user name. """
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            try:
                user = User.objects.get(username=username)
                if user.check_password(password):
                    return user
            except User.DoesNotExist:
                return None

    def get_user(self, user_id):
        """ Get a User object from the user_id. """
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Paso 2

En settings.py, modificamos AUTHENTICATION_BACKENDS incluyendo la ruta de nuestro archivo backends.py. En mi caso app.website.backends quedando de la siguiente forma.

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'app.website.backends.EmailAuthBackend'
)

Paso 3

Ya podemos realizar un sencillo login. Supongamos que estamos en views.py y recibo un formulario con dos campos de POST.

from django.contrib.auth import authenticate, login

def user_login(request):
    '''
    Login
    '''
    if request.method == 'POST':
            user = authenticate(
                username=request.POST['email'],
                password=request.POST['password']
            )
            if user is not None:
                login(request, user)
                return redirect(dashboard)

Y se acabó.

En realidad es un híbrido. Comprueba si existe el nombre de usuario y la contraseña, y en caso contrario realiza lo mismo con email y contraseña. Dos en uno.

Django 3.x

Paso 1

Creamos un nuevo documento Python con el nombre backends.py dentro de la aplicación (a la altura de views.py y models.py). Y pegamos el contenido:

from django.contrib.auth import backends
from django.contrib.auth.models import User

class EmailAuthBackend(backends.ModelBackend):
    """
    Email Authentication Backend

    Allows a user to sign in using an email/password pair, then check
    a username/password pair if email failed
    """

    def authenticate(self, username=None, password=None):
        """ Authenticate a user based on email address as the user name. """
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            try:
                user = User.objects.get(username=username)
                if user.check_password(password):
                    return user
            except User.DoesNotExist:
                return None

    def get_user(self, user_id):
        """ Get a User object from the user_id. """
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

Paso 2

En settings.py, modificamos AUTHENTICATION_BACKENDS incluyendo la ruta de nuestro archivo backends.py. En mi caso app.website.backends quedando de la siguiente forma.

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'app.website.backends.EmailAuthBackend'
)

Paso 3

Ya podemos realizar un sencillo login. Supongamos que estamos en views.py y recibo un formulario con dos campos de POST.

from django.contrib.auth import authenticate, login

def user_login(request):
    '''
    Login
    '''
    if request.method == 'POST':
            user = authenticate(
                username=request.POST['email'],
                password=request.POST['password']
            )
            if user is not None:
                login(request, user)
                return redirect(dashboard)

Y se acabó.

En realidad es un híbrido. Comprueba si existe el nombre de usuario y la contraseña, y en caso contrario realiza lo mismo con email y contraseña. Dos en uno.

Espero que este artículo sea de ayuda ya que prácticamente no encontré información al respecto.

Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.

Atribución/Reconocimiento-NoComercial-SinDerivados 4.0 Internacional

¿Me ayudas?

Comprame un café
Pulsa sobre la imagen

No te sientas obligado a realizar una donación, pero cada aportación mantiene el sitio en activo logrando que continúe existiendo y sea accesible para otras personas. Además me motiva a crear nuevo contenido.

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario

Tal vez también te interese...