Uso del sistema de autenticación de Django

Este documento explica el uso del sistema de autenticación de Django en su configuración por defecto. Esta configuración ha evolucionado para satisfacer las necesidades más comunes de los proyectos, maneja una gama razonablemente amplia de tareas y cuenta con una implementación cuidadosa de contraseñas y permisos. Para proyectos donde las necesidades de autenticación difieren de la predeterminada, Django admite extensiones y personalizaciones extensas del sistema de autenticación:doc:extension y personalización </topics/auth/customizing>.

La autenticación de Django proporciona tanto la autenticación como la autorización juntas y se conoce generalmente como el sistema de autenticación, ya que estas características están algo acopladas.

Objetos User

Los objetos User son el núcleo del sistema de autenticación. Representan típicamente a las personas que interactúan con tu sitio y se utilizan para habilitar cosas como la restricción de acceso, el registro de perfiles de usuario, la asociación de contenido con creadores, etc. Solo existe una clase de usuarios en el marco de autenticación de Django, es decir, los superusuarios 'superusers' o administradores 'staff' son solo objetos de usuario con atributos especiales establecidos, no diferentes clases de objetos de usuario.

Los atributos primarios del usuario por defecto son:

Vea la documentación de la API completa para una referencia completa, la documentación que sigue es más orientada a tareas.

Crear usuarios

La forma más directa de crear usuarios es utilizar la función auxiliar incluida create_user().

>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user("john", "lennon@thebeatles.com", "johnpassword")

# At this point, user is a User object that has already been saved
# to the database. You can continue to change its attributes
# if you want to change other fields.
>>> user.last_name = "Lennon"
>>> user.save()

Si tienes instalado el administrador Django, también puedes crear usuarios interactivamente.

Crear superusuarios

Crea superusuarios utilizando el comando createsuperuser.

$ python manage.py createsuperuser --username=joe --email=joe@example.com

Te pedirán una contraseña. Una vez que la hayas introducido, el usuario se creará de inmediato. Si omites las opciones --username o --email, te pedirá esos valores.

Cambiar contraseñas

Django no almacena contraseñas en texto claro en el modelo de usuario, sino solo una hash (consulte la documentación sobre cómo se gestionan las contraseñas <topics/auth/passwords> para obtener detalles completos). Por esta razón, no intentes manipular directamente el atributo contraseña del usuario. Esto es por lo que se utiliza una función auxiliar al crear un usuario.

Para cambiar la contraseña de un usuario, tienes varias opciones:

manage.py changepassword *nombre_de_usuario* ofrece una forma de cambiar la contraseña de un usuario desde la línea de comandos. Te pide que cambies la contraseña del usuario dado, que debes ingresar dos veces. Si coinciden, se cambiará la contraseña inmediatamente. Si no proporcionas un usuario, el comando intentará cambiar la contraseña cuyo nombre de usuario coincide con el usuario actual del sistema.

También puedes cambiar una contraseña programáticamente, utilizando set_password():

>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username="john")
>>> u.set_password("new password")
>>> u.save()

Si tienes instalado el administrador Django, también puedes cambiar las contraseñas de los usuarios en las páginas de administración del sistema de autenticación <auth-admin>.

Django proporciona vistas <built-in-auth-views> y formularios <built-in-auth-forms> que se pueden utilizar para permitir a los usuarios cambiar sus propias contraseñas.

Cambiar la contraseña de un usuario cerrará todas sus sesiones. Consulte <session-invalidation-on-password-change> para obtener detalles.

Autenticación de usuarios

authenticate(request=None, **credentials)[fuente]
aauthenticate(request=None, **credentials)

Versión asíncrona: aauthenticate()

Utiliza authenticate() para verificar un conjunto de credenciales. Recibe credenciales como argumentos clave, username y password para el caso por defecto, las compara con cada backend de autenticación, y devuelve un objeto User si las credenciales son válidas para algún backend. Si las credenciales no son válidas para ningún backend o si un backend lanza una excepción PermissionDenied, devuelve None. Por ejemplo:

from django.contrib.auth import authenticate

user = authenticate(username="john", password="secret")
if user is not None:
    # A backend authenticated the credentials
    ...
else:
    # No backend authenticated the credentials
    ...

request es un HttpRequest opcional que se pasa en el método authenticate() de los backends de autenticación.

Nota

Esta es una forma baja nivel para autenticar un conjunto de credenciales; por ejemplo, se utiliza por la clase RemoteUserMiddleware. A menos que estés escribiendo tu propio sistema de autenticación, probablemente no uses esto. En su lugar, si estás buscando una forma de iniciar sesión a un usuario, usa la clase LoginView.

Permisos y Autorización

Django viene con un sistema de permisos integrado. Proporciona una forma de asignar permisos a usuarios específicos y grupos de usuarios.

Se utiliza por el sitio administrativo de Django, pero estás bienvenido a usarlo en tu propio código.

El sitio administrativo de Django utiliza permisos de la siguiente manera:

  • El acceso para ver objetos está limitado a los usuarios con la «view» o «change» permiso para ese tipo de objeto.

  • El acceso para ver el formulario «add» y agregar un objeto está limitado a los usuarios con el «add» permiso para ese tipo de objeto.

  • El acceso para ver la lista de cambios, ver el formulario «change» y cambiar un objeto está limitado a los usuarios con el «change» permiso para ese tipo de objeto.

  • El acceso para eliminar un objeto está limitado a los usuarios con el «delete» permiso para ese tipo de objeto.

Los permisos pueden establecerse no solo por tipo de objeto, sino también por instancia específica del objeto. Al utilizar los métodos has_view_permission(), has_add_permission(), has_change_permission() y has_delete_permission() proporcionados por la clase ModelAdmin, es posible personalizar los permisos para diferentes instancias de objetos del mismo tipo.

Los objetos User tienen dos campos muchos a muchos: groups y user_permissions. Los objetos User pueden acceder a sus objetos relacionados de la misma manera que cualquier otro modelo Django:

myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()

Permisos por defecto

Cuando django.contrib.auth esté incluido en su configuración INSTALLED_APPS, asegurará que cuatro permisos por defecto – agregar, cambiar, eliminar y ver – se creen para cada modelo Django definido en una de sus aplicaciones instaladas.

Estos permisos se crearán cuando ejecute manage.py migrate; la primera vez que ejecute migrate después de agregar django.contrib.auth a INSTALLED_APPS, los permisos por defecto se crearán para todos los modelos instalados previamente, así como para cualquier nuevo modelo que esté siendo instalado en ese momento. Después de eso, creará permisos por defecto para nuevos modelos cada vez que ejecute manage.py migrate (la función que crea permisos está conectada al señal post_migrate).

Asumiendo que tiene una aplicación con un app_label foo y un modelo llamado Bar, para probar los permisos básicos debería utilizar:

  • agregar: user.has_perm('foo.add_bar')

  • cambiar: user.has_perm('foo.change_bar')

  • eliminar: user.has_perm('foo.delete_bar')

  • ver: user.has_perm('foo.view_bar)

El modelo de permisos Permission se accede raramente directamente.

Grupos

Los modelos django.contrib.auth.models.Group son una forma genérica de categorizar a los usuarios para poder aplicarles permisos, o algún otro label, a esos usuarios. Un usuario puede pertenecer a cualquier número de grupos.

Un usuario en un grupo tiene automáticamente los permisos concedidos a ese grupo. Por ejemplo, si el grupo Editores del sitio tiene el permiso puedo editar la página principal, cualquier usuario en ese grupo tendrá ese permiso.

Más allá de los permisos, los grupos son una forma conveniente de categorizar a los usuarios para darles algún label o funcionalidad extendida. Por ejemplo, podrías crear un grupo 'Usuarios especiales', y podrías escribir código que les diera acceso a una sección privada del sitio solo para miembros, o enviarles mensajes de correo electrónico solo para miembros.

Creación programática de permisos

Si bien los permisos personalizados <custom-permissions> pueden definirse dentro de la clase Meta de un modelo, también puedes crear permisos directamente. Por ejemplo, puedes crear el permiso puedo publicar para el modelo BlogPost en myapp:

from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
    codename="can_publish",
    name="Can Publish Posts",
    content_type=content_type,
)

El permiso entonces se puede asignar a un usuario User a través de su atributo user_permissions o a un grupo Group a través de su atributo permissions.

Los modelos proxy necesitan su propio tipo de contenido

Si deseas crear permisos para un modelo proxy, pasa for_concrete_model=False a la función ContentTypeManager.get_for_model() para obtener el ContentType adecuado:

content_type = ContentType.objects.get_for_model(
    BlogPostProxy, for_concrete_model=False
)

Caching de permisos

La clase ModelBackend almacena los permisos en el objeto del usuario después de la primera vez que se necesitan para una comprobación de permisos. Esto es típicamente suficiente para el ciclo de solicitud-respuesta ya que los permisos no se comproban inmediatamente después de ser agregados (por ejemplo, en la interfaz administrativa). Si estás agregando permisos y comprobándolos inmediatamente después, por ejemplo en una prueba o vista, la solución más fácil es reflechar el usuario desde la base de datos. Por ejemplo:

from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404

from myapp.models import BlogPost


def user_gains_perms(request, user_id):
    user = get_object_or_404(User, pk=user_id)
    # any permission check will cache the current set of permissions
    user.has_perm("myapp.change_blogpost")

    content_type = ContentType.objects.get_for_model(BlogPost)
    permission = Permission.objects.get(
        codename="change_blogpost",
        content_type=content_type,
    )
    user.user_permissions.add(permission)

    # Checking the cached permission set
    user.has_perm("myapp.change_blogpost")  # False

    # Request new instance of User
    # Be aware that user.refresh_from_db() won't clear the cache.
    user = get_object_or_404(User, pk=user_id)

    # Permission cache is repopulated from the database
    user.has_perm("myapp.change_blogpost")  # True

    ...

Modelos proxy

Los modelos proxy funcionan exactamente de la misma manera que los modelos concretos. Los permisos se crean utilizando el propio tipo de contenido del modelo proxy. Los modelos proxy no heredan los permisos del modelo concreto que lo subclasa:

class Person(models.Model):
    class Meta:
        permissions = [("can_eat_pizzas", "Can eat pizzas")]


class Student(Person):
    class Meta:
        proxy = True
        permissions = [("can_deliver_pizzas", "Can deliver pizzas")]
>>> # Fetch the content type for the proxy model.
>>> content_type = ContentType.objects.get_for_model(Student, for_concrete_model=False)
>>> student_permissions = Permission.objects.filter(content_type=content_type)
>>> [p.codename for p in student_permissions]
['add_student', 'change_student', 'delete_student', 'view_student',
'can_deliver_pizzas']
>>> for permission in student_permissions:
...     user.user_permissions.add(permission)
...
>>> user.has_perm("app.add_person")
False
>>> user.has_perm("app.can_eat_pizzas")
False
>>> user.has_perms(("app.add_student", "app.can_deliver_pizzas"))
True

Autenticación en solicitudes web

Django utiliza sesiones y middleware para conectar el sistema de autenticación a los objetos de solicitud request.

Estos proporcionan un atributo solicitud.usuario y un método asincrónico solicitud.auser en cada solicitud que representa al usuario actual. Si el usuario actual no ha iniciado sesión, este atributo se establecerá en una instancia de AnonymousUser, de lo contrario será una instancia de User.

Puedes distinguirlos mediante is_authenticated, como se muestra a continuación:

if request.user.is_authenticated:
    # Do something for authenticated users.
    ...
else:
    # Do something for anonymous users.
    ...

O en una vista asincrónica

user = await request.auser()
if user.is_authenticated:
    # Do something for authenticated users.
    ...
else:
    # Do something for anonymous users.
    ...

Cómo iniciar sesión un usuario

Si tienes un usuario autenticado que deseas unir a la sesión actual - esto se hace con la función login().

login(request, user, backend=None)[fuente]
alogin(request, user, backend=None)

Versión asíncrona: alogin()

Para iniciar sesión a un usuario, desde una vista, utiliza la función login(). Esta función recibe un objeto HttpRequest y un objeto User. La función login() almacena el ID del usuario en la sesión utilizando el marco de sesiones de Django.

Ten en cuenta que cualquier dato establecido durante la sesión anónima se retiene en la sesión después de que un usuario inicia sesión.

Este ejemplo muestra cómo podrías utilizar tanto authenticate() como login():

from django.contrib.auth import authenticate, login


def my_view(request):
    username = request.POST["username"]
    password = request.POST["password"]
    user = authenticate(request, username=username, password=password)
    if user is not None:
        login(request, user)
        # Redirect to a success page.
        ...
    else:
        # Return an 'invalid login' error message.
        ...

Seleccionar el backend de autenticación

Cuando un usuario inicia sesión, se almacenan en la sesión del usuario su ID y el backend utilizado para la autenticación. Esto permite que el mismo backend de autenticación <authentication-backends> pueda recuperar los detalles del usuario en una solicitud futura. El backend de autenticación a almacenar en la sesión se selecciona de la siguiente manera:

  1. Utiliza el valor del argumento backend opcional, si está presente.

  2. Utiliza el valor de la propiedad user.backend, si está presente. Esto permite emparejar authenticate() y login(): authenticate() establece la propiedad user.backend en el objeto de usuario que devuelve.

  3. Utiliza el backend en AUTHENTICATION_BACKENDS, si solo hay uno.

  4. De lo contrario, se levanta una excepción.

En los casos 1 y 2, el valor del argumento backend o la propiedad user.backend debe ser un string de ruta de importación puntuada (como se encuentra en AUTHENTICATION_BACKENDS), no la clase de backend real.

Cómo cerrar sesión a un usuario

logout(request)[fuente]
alogout(request)

Versión asíncrona: alogout()

Para cerrar sesión a un usuario que ha sido logueado mediante django.contrib.auth.login(), utilice django.contrib.auth.logout() dentro de su vista. Recibe un objeto HttpRequest y no tiene valor de retorno. Ejemplo:

from django.contrib.auth import logout


def logout_view(request):
    logout(request)
    # Redirect to a success page.

Ten en cuenta que logout() no lanza ningún error si el usuario no estaba logueado.

Cuando llames a logout(), los datos de sesión para la solicitud actual se eliminan completamente. Todos los datos existentes son eliminados. Esto es para evitar que otra persona utilice el mismo navegador web para iniciar sesión y tener acceso a los datos de sesión del usuario anterior. Si deseas poner algo en la sesión que esté disponible para el usuario inmediatamente después de cerrar sesión, hazlo después de llamar a django.contrib.auth.logout().

Limitando el acceso a usuarios logueados

La forma bruta

La forma bruta para limitar el acceso a páginas es comprobar si request.user.is_authenticated y redirigir a una página de inicio de sesión:

from django.conf import settings
from django.shortcuts import redirect


def my_view(request):
    if not request.user.is_authenticated:
        return redirect(f"{settings.LOGIN_URL}?next={request.path}")
    # ...

o mostrar un mensaje de error:

from django.shortcuts import render


def my_view(request):
    if not request.user.is_authenticated:
        return render(request, "myapp/login_error.html")
    # ...

El decorador login_required

login_required(redirect_field_name='next', login_url=None)[fuente]

Como atajo, puedes utilizar el conveniente decorador login_required()

from django.contrib.auth.decorators import login_required


@login_required
def my_view(request): ...

login_required() hace lo siguiente:

  • Si el usuario no está conectado, redirige a settings.LOGIN_URL, pasando la ruta absoluta actual en la cadena de consulta. Ejemplo: /accounts/login/?next=/polls/3/.

  • Si el usuario está conectado, ejecuta la vista normalmente. El código de la vista está libre para suponer que el usuario está conectado.

Por defecto, el camino al que se debe redirigir al usuario después de una autenticación exitosa se almacena en un parámetro de cadena de consulta llamado "next". Si preferirías utilizar un nombre diferente para este parámetro, login_required() acepta el parámetro opcional redirect_field_name

from django.contrib.auth.decorators import login_required


@login_required(redirect_field_name="my_redirect_field")
def my_view(request): ...

Ten en cuenta que si proporcionas un valor a redirect_field_name, es probable que necesites personalizar tu plantilla de inicio de sesión también, ya que la variable del contexto de la plantilla que almacena el camino de redirección utilizará el valor de redirect_field_name como clave en lugar de "next" (el valor por defecto).

login_required() acepta también un parámetro opcional login_url. Ejemplo:

from django.contrib.auth.decorators import login_required


@login_required(login_url="/accounts/login/")
def my_view(request): ...

Ten en cuenta que si no especificas el parámetro login_url, deberás asegurarte de que settings.LOGIN_URL y tu vista de inicio de sesión estén asociados correctamente. Por ejemplo, utilizando los valores por defecto, agrega las siguientes líneas a tu URLconf:

from django.contrib.auth import views as auth_views

path("accounts/login/", auth_views.LoginView.as_view()),

La traducción de los textos es la siguiente:

Nota

El decorador login_required NO verifica la bandera is_active del usuario, pero los backends de autenticación por defecto rechazan a usuarios inactivos (AUTHENTICATION_BACKENDS).

Ver también

Si estás escribiendo vistas personalizadas para Django’s admin (o necesitas el mismo control de autorización que las vistas integradas utilizan), puede encontrar útil el decorador django.contrib.admin.views.decorators.staff_member_required() como alternativa a login_required().

Se ha agregado soporte para envolver funciones de vistas asíncronas.

La clase mixin LoginRequiredMixin

Al utilizar vistas basadas en clases (class-based views), puedes lograr el mismo comportamiento que con login_required utilizando la clase mixin LoginRequiredMixin. Esta clase mixin debe estar en la posición más a la izquierda de la lista de herencia.

class LoginRequiredMixin[fuente]

Si una vista utiliza esta clase mixin, todas las solicitudes de usuarios no autenticados serán redirigidas a la página de inicio de sesión o mostrarán un error HTTP 403 Forbidden, dependiendo del parámetro raise_exception.

Puedes establecer cualquier uno de los parámetros de AccessMixin para personalizar el manejo de usuarios no autorizados:

from django.contrib.auth.mixins import LoginRequiredMixin


class MyView(LoginRequiredMixin, View):
    login_url = "/login/"
    redirect_field_name = "redirect_to"

Nota

Justo como el decorador login_required, esta clase mixin NO verifica la bandera is_active del usuario, pero los backends de autenticación por defecto rechazan a usuarios inactivos (AUTHENTICATION_BACKENDS).

El decorador login_not_required

When la clase ~django.contrib.auth.middleware.LoginRequiredMiddleware está instalada, todas las vistas requieren autenticación por defecto. Algunas vistas, como la vista de inicio de sesión, pueden necesitar deshabilitar este comportamiento.

login_not_required()[fuente]

Permite solicitudes no autenticadas para esta vista cuando la clase ~django.contrib.auth.middleware.LoginRequiredMiddleware está instalada.

Limitar el acceso a usuarios conectados que pasan una prueba

Para limitar el acceso basado en ciertas permisos o alguna otra prueba, harías lo mismo que se describe en la sección anterior.

Puedes ejecutar tu prueba sobre request.user <django.http.HttpRequest.user> directamente en la vista. Por ejemplo, esta vista verifica si el usuario tiene un correo electrónico en el dominio deseado y, si no es así, redirige a la página de inicio de sesión:

from django.shortcuts import redirect


def my_view(request):
    if not request.user.email.endswith("@example.com"):
        return redirect("/login/?next=%s" % request.path)
    # ...
user_passes_test(test_func, login_url=None, redirect_field_name='next')[fuente]

Como atajo, puedes utilizar el decorador conveniente user_passes_test que realiza una redirección cuando el llamable devuelve False:

from django.contrib.auth.decorators import user_passes_test


def email_check(user):
    return user.email.endswith("@example.com")


@user_passes_test(email_check)
def my_view(request): ...

La función ~django.contrib.auth.decorators.user_passes_test toma un argumento requerido: un llamable que toma un objeto User <django.contrib.auth.models.User> y devuelve True si el usuario está autorizado a ver la página. Ten en cuenta que ~django.contrib.auth.decorators.user_passes_test no verifica automáticamente que el objeto User <django.contrib.auth.models.User> no sea anónimo.

La función ~django.contrib.auth.decorators.user_passes_test toma dos argumentos opcionales:

login_url

Te permite especificar la URL a la que se redirigirá a los usuarios que no pasen la prueba. Puede ser una página de inicio de sesión y, por defecto, utiliza settings.LOGIN_URL <LOGIN_URL> si no lo especificas.

redirect_field_name

Lo mismo que para login_required(). Establecerlo en None lo elimina del URL, lo que puede ser útil si estás redirigiendo a usuarios que no pasan la prueba a una página de inicio de sesión donde no hay «siguiente página».

Por ejemplo:

@user_passes_test(email_check, login_url="/login/")
def my_view(request): ...

Se agregó soporte para envolver funciones de vistas asíncronas y utilizar llamables de pruebas asíncronas.

class UserPassesTestMixin[fuente]

Al usar vistas basadas en clases, puedes utilizar el UserPassesTestMixin para hacer esto.

test_func()[fuente]

Tienes que sobrescribir el método test_func() de la clase para proporcionar la prueba que se ejecuta. Además, puedes establecer cualquier parámetro de AccessMixin para personalizar el manejo de usuarios no autorizados:

from django.contrib.auth.mixins import UserPassesTestMixin


class MyView(UserPassesTestMixin, View):
    def test_func(self):
        return self.request.user.email.endswith("@example.com")
get_test_func()[fuente]

También puedes sobrescribir el método get_test_func() para que el mixin utilice una función con un nombre diferente para sus comprobaciones (en lugar de test_func()).

Pila de UserPassesTestMixin

Debido a la forma en que está implementado UserPassesTestMixin, no puedes apilarlos en tu lista de herencia. El siguiente NO funciona:

class TestMixin1(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.email.endswith("@example.com")


class TestMixin2(UserPassesTestMixin):
    def test_func(self):
        return self.request.user.username.startswith("django")


class MyView(TestMixin1, TestMixin2, View): ...

Si TestMixin1 llamara a super() y tomara ese resultado en cuenta, TestMixin1 ya no funcionaría de forma independiente.

El decorador permission_required

permission_required(perm, login_url=None, raise_exception=False)[fuente]

Es un tarea relativamente común verificar si un usuario tiene una permiso particular. Para ese motivo, Django proporciona un atajo para ese caso: el decorador permission_required():

from django.contrib.auth.decorators import permission_required


@permission_required("polls.add_choice")
def my_view(request): ...

Al igual que el método has_perm(), los nombres de permisos tienen la forma "<etiqueta_de_aplicación>.<nombre_del_código_de_permiso>" (es decir, polls.add_choice para un permiso en un modelo de la aplicación polls).

El decorador también puede tomar una iterable de permisos, en cuyo caso el usuario debe tener todos los permisos para acceder a la vista.

Ten en cuenta que permission_required() también toma un parámetro login_url opcional:

from django.contrib.auth.decorators import permission_required


@permission_required("polls.add_choice", login_url="/loginpage/")
def my_view(request): ...

Al igual que en el decorador login_required(), login_url tiene como valor por defecto la configuración de settings.LOGIN_URL.

Si se da el parámetro raise_exception, el decorador levantará una PermissionDenied y mostrará la vista 403 (HTTP Forbidden) en lugar de redirigir a la página de inicio de sesión.

Si deseas usar raise_exception pero también darle a tus usuarios la oportunidad de iniciar sesión primero, puedes agregar el decorador login_required():

from django.contrib.auth.decorators import login_required, permission_required


@login_required
@permission_required("polls.add_choice", raise_exception=True)
def my_view(request): ...

Esto evita también un bucle de redirección cuando la vista LoginView tiene redirect_authenticated_user=True y el usuario iniciado no tiene todos los permisos requeridos.

Se ha agregado soporte para envolver funciones de vistas asíncronas.

La clase mixin PermissionRequiredMixin

Para aplicar comprobaciones de permiso a vistas basadas en clases, puedes usar la clase mixin PermissionRequiredMixin:

class PermissionRequiredMixin[fuente]

Esta mezcla, al igual que el decorador permission_required, verifica si el usuario que accede a una vista tiene todos los permisos dados. Debes especificar el permiso (o un iterable de permisos) utilizando el parámetro permission_required:

from django.contrib.auth.mixins import PermissionRequiredMixin


class MyView(PermissionRequiredMixin, View):
    permission_required = "polls.add_choice"
    # Or multiple of permissions:
    permission_required = ["polls.view_choice", "polls.change_choice"]

Puedes establecer cualquier de los parámetros de AccessMixin para personalizar la gestión de usuarios no autorizados.

También puedes sobreescribir estos métodos:

get_permission_required()[fuente]

Devuelve un iterable de nombres de permisos utilizados por la mezcla. Por defecto, devuelve el atributo permission_required, convertido a una tupla si es necesario.

has_permission()[fuente]

Devuelve un booleano denotando si el usuario actual tiene permiso para ejecutar la vista decorada. Por defecto, esto devuelve el resultado de llamar a has_perms() con la lista de permisos devuelta por get_permission_required().

Redireccionar solicitudes no autorizadas en vistas basadas en clase

Para facilitar la gestión de restricciones de acceso en vistas basadas en clase, la mezcla AccessMixin se puede utilizar para configurar el comportamiento de una vista cuando se deniega el acceso. Los usuarios autenticados se deniegan el acceso con una respuesta HTTP 403 Forbidden. Los usuarios anónimos se redirigen a la página de inicio de sesión o se muestra una respuesta HTTP 403 Forbidden, dependiendo del atributo raise_exception de AccessMixin.

class AccessMixin[fuente]
login_url

Valor por defecto devuelto para get_login_url(). Por defecto, es None en cuyo caso get_login_url() cae en la cuenta a settings.LOGIN_URL.

permission_denied_message

Valor por defecto devuelto para get_permission_denied_message(). Por defecto, es una cadena vacía.

redirect_field_name

Valor por defecto devuelto para get_redirect_field_name(). Por defecto, es "next".

raise_exception

Si esta atributo está configurado en True, se levanta una excepción PermissionDenied cuando las condiciones no están satisfechas. Cuando es False (el valor por defecto), los usuarios anónimos son redirigidos a la página de inicio de sesión.

get_login_url()[fuente]

Devuelve la URL que los usuarios que no pasan la prueba serán redirigidos. Devuelve login_url si está configurado, o settings.LOGIN_URL en caso contrario.

get_permission_denied_message()[fuente]

Cuando raise_exception es True, este método se puede utilizar para controlar el mensaje de error pasado al manejo del error para su visualización por parte del usuario. Devuelve el atributo permission_denied_message por defecto.

get_redirect_field_name()[fuente]

Devuelve el nombre del parámetro de consulta que contenga la URL a la que el usuario debería ser redirigido después de un inicio de sesión exitoso. Si estableces esto en None, no se agregará ningún parámetro de consulta. Devuelve el atributo redirect_field_name por defecto.

handle_no_permission()[fuente]

Según el valor de raise_exception, el método levanta una excepción PermissionDenied o redirige al usuario a la login_url, opcionalmente incluyendo el redirect_field_name si está configurado.

Invalidez de sesión en cambio de contraseña

Si tu modelo de usuario AUTH_USER_MODEL hereda de AbstractBaseUser o implementa su propio método get_session_auth_hash() , las sesiones autenticadas incluirán el hash devuelto por esta función. En el caso de AbstractBaseUser, este es un HMAC del campo de contraseña. Django verifica que el hash en la sesión para cada solicitud coincida con el calculado durante la solicitud. Esto permite a un usuario cerrar todas sus sesiones cambiando su contraseña.

Las vistas de cambio de contraseña incluidas por defecto con Django, PasswordChangeView y la vista user_change_password en el módulo django.contrib.auth admin, actualizan la sesión con el nuevo hash de contraseña para que un usuario cambiando su propia contraseña no se cierre a sí mismo. Si tienes una vista personalizada de cambio de contraseña y deseas tener comportamiento similar, utiliza la función update_session_auth_hash().

update_session_auth_hash(request, user)[fuente]
aupdate_session_auth_hash(request, user)

Versión asíncrona: aupdate_session_auth_hash()

Esta función toma el objeto de solicitud actual y el objeto de usuario actualizado desde el que se derivará el nuevo hash de sesión y actualiza el hash de sesión apropiadamente. También rota la clave de sesión para que una cookie de sesión robada sea invalidada.

Since get_session_auth_hash() está basado en SECRET_KEY, los valores de la clave secreta deben rotarse para evitar invalidar las sesiones existentes cuando se actualiza el sitio para utilizar una nueva clave secreta. Consulte SECRET_KEY_FALLBACKS para obtener más detalles.

from django.contrib.auth import update_session_auth_hash


def password_change(request):
    if request.method == "POST":
        form = PasswordChangeForm(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            update_session_auth_hash(request, form.user)
    else:
        ...

Nota

Autenticación

Django proporciona varias vistas que puedes usar para manejar la autenticación, el cierre de sesión y la gestión de contraseñas. Estas utilizan las formas de autenticación de Django pero también puedes pasar tus propias formas.

Plantillas

Django no proporciona una plantilla predeterminada para las vistas de autenticación. Debes crear tus propias plantillas para las vistas que desees utilizar. El contexto de la plantilla se documenta en cada vista, consulte todas las vistas de autenticación.

Uso de las vistas

Hay diferentes formas de implementar estas vistas en tu proyecto. La forma más fácil es incluir el URLconf proporcionado en django.contrib.auth.urls en tu propio URLconf, por ejemplo:

urlpatterns = [
    path("accounts/", include("django.contrib.auth.urls")),
]

Esto incluye los siguientes patrones de URL:

accounts/login/ [name='login']
accounts/logout/ [name='logout']
accounts/password_change/ [name='password_change']
accounts/password_change/done/ [name='password_change_done']
accounts/password_reset/ [name='password_reset']
accounts/password_reset/done/ [name='password_reset_done']
accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/reset/done/ [name='password_reset_complete']

Las vistas proporcionan un nombre de URL para una referencia más sencilla. Consulte la documentación sobre URLs para obtener más detalles sobre el uso de patrones de URL con nombres.

Si deseas tener más control sobre tus URLs, puedes referirte a una vista específica en tu URLconf:

from django.contrib.auth import views as auth_views

urlpatterns = [
    path("change-password/", auth_views.PasswordChangeView.as_view()),
]

Los textos traducidos manteniendo todas sus etiquetas intactas son:

urlpatterns = [
    path(
        "change-password/",
        auth_views.PasswordChangeView.as_view(template_name="change-password.html"),
    ),
]

Todas las vistas son clase basada, lo que te permite personalizarlas fácilmente creando subclases.

Todas las vistas de autenticación

Esta es una lista con todas las vistas que proporciona django.contrib.auth. Para detalles de implementación, vea usando las vistas.

class LoginView[fuente]

Nombre de URL: login

Consulte la documentación sobre URLs <topics/http/urls> para obtener más información sobre el uso de patrones de URL nombrados.

Métodos y Atributos

template_name

El nombre del template a mostrar para la vista utilizada para iniciar sesión al usuario. Por defecto, es registration/login.html.

next_page

La URL a redirigir después de iniciar sesión. Por defecto, es LOGIN_REDIRECT_URL.

redirect_field_name

El nombre del campo GET que contiene la URL a redirigir después de iniciar sesión. Por defecto, es next. Sobreescribe la URL predeterminada si se pasa el parámetro GET correspondiente.

authentication_form

Un callable (generalmente una clase de formulario) para utilizar para la autenticación. Por defecto es AuthenticationForm.

extra_context

Un diccionario de datos de contexto que se agregarán a los datos de contexto predeterminados pasados al template.

redirect_authenticated_user

Una booleana que controla si los usuarios autenticados accediendo a la página de inicio de sesión serán redirigidos como si hubieran iniciado sesión con éxito. Por defecto es False.

Advertencia

Si habilitas redirect_authenticated_user, otros sitios web podrán determinar si sus visitantes están autenticados en tu sitio solicitando URLs de redirección a archivos de imagen en tu sitio web. Para evitar esta «fuga de información sobre huella digital social» , hospeda todos los imágenes y tu favicon en un dominio separado.

Habilitar redirect_authenticated_user también puede resultar en un bucle de redirección cuando se utiliza el decorador permission_required() a menos que se utilice el parámetro raise_exception.

success_url_allowed_hosts

Un conjunto de hosts, además de request.get_host(), que son seguros para redirigir después del inicio de sesión. Por defecto es un conjunto vacío.

get_default_redirect_url()[fuente]

Devuelve la URL a la que redirigir después del inicio de sesión. La implementación predeterminada resuelve y devuelve next_page si está configurado, o LOGIN_REDIRECT_URL en caso contrario.

Aquí está lo que hace LoginView:

  • Si se llama mediante GET, muestra un formulario de inicio de sesión que POST a la misma URL. Más información sobre esto más adelante.

  • Si se llama mediante POST con credenciales de usuario suministradas, intenta iniciar sesión al usuario. Si el inicio de sesión es exitoso, la vista redirige a la URL especificada en next. Si next no está configurado, redirige a settings.LOGIN_REDIRECT_URL (que por defecto es /accounts/profile/). Si el inicio de sesión no es exitoso, vuelve a mostrar el formulario de inicio de sesión.

Es tu responsabilidad proporcionar el código HTML para la plantilla de inicio de sesión, llamada por defecto registration/login.html. Esta plantilla recibe cuatro variables de contexto de plantilla:

  • form: Un objeto Form que representa la forma de autenticación AuthenticationForm.

  • next: La URL a la que se redirige después del inicio de sesión exitoso. Esta puede contener una cadena de consulta, también.

  • site: El sitio actual Site, según el parámetro de configuración SITE_ID. Si no tienes instalado el marco de sitios, esta será establecida en una instancia de RequestSite, que deriva el nombre y dominio del sitio a partir de la solicitud actual HttpRequest.

  • site_name: Un alias para site.name. Si no tienes instalado el marco de sitios, esta será establecida en el valor de request.META['SERVER_NAME']. Para más información sobre sitios, consulta El «framework de sitios».

Si prefieres no llamar a la plantilla registration/login.html, puedes pasar el parámetro template_name mediante los argumentos adicionales de la función as_view en tu archivo URLconf. Por ejemplo, esta línea del archivo URLconf utilizaría en su lugar myapp/login.html:

path("accounts/login/", auth_views.LoginView.as_view(template_name="myapp/login.html")),

También puedes especificar el nombre del campo GET que contiene la URL a la que se redirige después de inicio de sesión utilizando redirect_field_name. Por defecto, el campo se llama next.

Aquí tienes un ejemplo de plantilla registration/login.html que puedes utilizar como punto de partida. Supone que tienes una plantilla base.html que define un bloque content:

{% extends "base.html" %}

{% block content %}

{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}

{% if next %}
    {% if user.is_authenticated %}
    <p>Your account doesn't have access to this page. To proceed,
    please login with an account that has access.</p>
    {% else %}
    <p>Please login to see this page.</p>
    {% endif %}
{% endif %}

<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
    <td>{{ form.username.label_tag }}</td>
    <td>{{ form.username }}</td>
</tr>
<tr>
    <td>{{ form.password.label_tag }}</td>
    <td>{{ form.password }}</td>
</tr>
</table>

<input type="submit" value="login">
<input type="hidden" name="next" value="{{ next }}">
</form>

{# Assumes you set up the password_reset view in your URLconf #}
<p><a href="{% url 'password_reset' %}">Lost password?</a></p>

{% endblock %}

Si has personalizado la autenticación (consultar Customizando Autenticación), puedes utilizar una forma de autenticación personalizada estableciendo el atributo authentication_form. Esta forma debe aceptar un argumento request en su método __init__() y proporcionar un método get_user() que devuelve la instancia del objeto usuario autenticado (este método solo se llama después de una validación exitosa de la forma).

class LogoutView[fuente]

Inicia sesión a un usuario en solicitudes POST.

Nombre de URL: logout

Atributos:

next_page

La URL a la que redirigir después del cierre de sesión. Por defecto, LOGOUT_REDIRECT_URL.

template_name

El nombre completo de un template para mostrar después de que el usuario se haya cerrado la sesión. Por defecto, registration/logged_out.html.

redirect_field_name

El nombre de un campo GET conteniendo la URL a la que redirigir después del cierre de sesión. Por defecto, 'next'. Sobreescribe la URL next_page si se pasa el parámetro GET correspondiente.

extra_context

Un diccionario de datos de contexto que se agregarán a los datos de contexto predeterminados pasados al template.

success_url_allowed_hosts

Un conjunto de hosts, además de request.get_host(), que son seguros para redirigir después del cierre de sesión. Por defecto, un conjunto vacío.

Contexto de plantilla:

  • title: La cadena «Cerrado la sesión», localizada.

  • site: El sitio actual Site, según el parámetro de configuración SITE_ID. Si no tienes instalado el marco de sitios, esta será establecida en una instancia de RequestSite, que deriva el nombre y dominio del sitio a partir de la solicitud actual HttpRequest.

  • site_name: Un alias para site.name. Si no tienes instalado el marco de sitios, esta será establecida en el valor de request.META['SERVER_NAME']. Para más información sobre sitios, consulta El «framework de sitios».

logout_then_login(request, login_url=None)[fuente]

Cierra a un usuario en solicitudes POST, luego redirige a la página de inicio de sesión.

Nombre de URL: No se proporciona una URL por defecto

Argumentos opcionales:

  • login_url: La URL de la página de inicio de sesión a la que redirigir. Por defecto, se utiliza settings.LOGIN_URL si no se proporciona.

class PasswordChangeView[fuente]

Nombre de URL: password_change

Permite a un usuario cambiar su contraseña.

Atributos:

template_name

El nombre completo de un template para utilizar al mostrar el formulario de cambio de contraseña. Por defecto, se utiliza registration/password_change_form.html si no se proporciona.

success_url

La URL a la que redirigir después de un cambio de contraseña exitoso. Por defecto, es 'password_change_done'.

form_class

Un formulario personalizado «cambiar contraseña» que debe aceptar el argumento de palabra clave user. El formulario es responsable del cambio real de la contraseña del usuario. Por defecto, se utiliza PasswordChangeForm.

extra_context

Un diccionario de datos de contexto que se agregarán a los datos de contexto predeterminados pasados al template.

Contexto de plantilla:

  • form: El formulario de cambio de contraseña (consulte form_class anterior).

class PasswordChangeDoneView[fuente]

Nombre de URL: password_change_done

La página mostrada después de que un usuario haya cambiado su contraseña.

Atributos:

template_name

El nombre completo de un template para usar. Por defecto es registration/password_change_done.html si no se proporciona.

extra_context

Un diccionario de datos de contexto que se agregarán a los datos de contexto predeterminados pasados al template.

class PasswordResetView[fuente]

Nombre URL: password_reset

Permite a un usuario restablecer su contraseña generando un enlace único que puede usarse para restablecer la contraseña y enviándolo al correo electrónico registrado del usuario.

Esta vista enviará un correo electrónico si se cumplen las siguientes condiciones:

  • La dirección de correo electrónico proporcionada existe en el sistema.

  • El usuario solicitado está activo (User.is_active es True).

  • El usuario solicitado tiene una contraseña válida. Los usuarios marcados con una contraseña inválida (consulte set_unusable_password()) no están permitidos para solicitar un restablecimiento de contraseña para evitar el uso indebido cuando se utiliza una fuente de autenticación externa como LDAP.

Si ninguna de estas condiciones se cumple, no se enviará correo electrónico, pero al usuario no se le mostrará ningún mensaje de error. Esto previene que se revele información a posibles atacantes. Si deseas proporcionar un mensaje de error en este caso, puedes heredar de PasswordResetForm y utilizar el atributo form_class.

Nota

Ten en cuenta que enviar correos electrónicos cuesta tiempo extra, por lo que podrías ser vulnerable a un ataque de enumeración de direcciones de correo electrónico mediante la duración del tiempo debido a una diferencia entre la duración de una solicitud de restablecimiento para una dirección de correo electrónico existente y la duración de una solicitud de restablecimiento para una dirección de correo electrónico inexistente. Para reducir el overhead, puedes utilizar un paquete de terceros que permite enviar correos electrónicos de manera asíncrona, por ejemplo django-mailer.

Atributos:

template_name

El nombre completo de un template para usar para mostrar el formulario de restablecimiento de contraseña. Por defecto es registration/password_reset_form.html si no se proporciona.

form_class

El formulario que se utilizará para obtener el correo electrónico del usuario para restablecer la contraseña. Por defecto, utiliza PasswordResetForm.

email_template_name

El nombre completo de un plantilla a usar para generar el correo electrónico con el enlace de restablecimiento de contraseña. Por defecto, utiliza registration/password_reset_email.html si no se proporciona.

subject_template_name

El nombre completo de una plantilla a utilizar para el asunto del correo electrónico con el enlace de restablecimiento de contraseña. Por defecto, utiliza registration/password_reset_subject.txt si no se proporciona.

token_generator

Instancia de la clase que verificará el enlace temporal. Por defecto, utiliza default_token_generator, que es una instancia de django.contrib.auth.tokens.PasswordResetTokenGenerator.

success_url

La URL a redirigir después de una solicitud exitosa de restablecimiento de contraseña. Por defecto, utiliza 'password_reset_done'.

from_email

Una dirección de correo electrónico válida. Por defecto, Django utiliza la DEFAULT_FROM_EMAIL.

extra_context

Un diccionario de datos de contexto que se agregarán a los datos de contexto predeterminados pasados al template.

html_email_template_name

El nombre completo de una plantilla a utilizar para generar un correo electrónico multipart con el enlace de restablecimiento de contraseña y formato text/html. Por defecto, no se envía correo electrónico HTML.

extra_email_context

Un diccionario de datos de contexto que estará disponible en la plantilla del correo electrónico. Puede utilizarse para sobreescribir valores de contexto de plantilla por defecto listados a continuación, e.g. domain.

Contexto de plantilla:

  • form: El formulario (consulte form_class anterior) para restablecer la contraseña del usuario.

Contexto de la plantilla del correo electrónico:

  • email: Un alias para user.email

  • user: El usuario actual (User) según el campo de formulario email. Solo los usuarios activos pueden restablecer sus contraseñas (User.is_active es Verdadero).

  • site_name: Un alias para site.name. Si no tienes instalado el marco de sitios, esta será establecida en el valor de request.META['SERVER_NAME']. Para más información sobre sitios, consulta El «framework de sitios».

  • domain: Un alias para site.domain. Si no tienes instalado el framework del sitio, este valor se establecerá en el valor de request.get_host().

  • protocol: http o https

  • uid: La clave primaria del usuario codificada en base 64.

  • token: Token para verificar que la URL de restablecimiento es válida.

Ejemplo de registration/password_reset_email.html (plantilla de cuerpo de correo electrónico):

Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}

Se utiliza el mismo contexto de plantillas para la plantilla de asunto. El asunto debe ser una cadena de texto plano en línea simple.

class PasswordResetDoneView[fuente]

Nombre de URL: password_reset_done

La página mostrada después de que un usuario ha sido enviado un enlace para restablecer su contraseña. Esta vista se llama por defecto si la vista PasswordResetView no tiene una URL explícita configurada para success_url.

Nota

Si la dirección de correo electrónico proporcionada no existe en el sistema, el usuario está inactivo o tiene una contraseña inválida, el usuario seguirá siendo redirigido a esta vista pero no se enviará ningún correo electrónico.

Atributos:

template_name

El nombre completo del template a utilizar. Por defecto utiliza registration/password_reset_done.html si no se proporciona.

extra_context

Un diccionario de datos de contexto que se agregarán a los datos de contexto predeterminados pasados al template.

class PasswordResetConfirmView[fuente]

Nombre de URL: password_reset_confirm

Presenta un formulario para ingresar una nueva contraseña.

Argumentos de palabra clave desde la URL:

  • uidb64: El id del usuario codificado en base 64.

  • token: Token para verificar que la contraseña es válida.

Atributos:

template_name

El nombre completo del template para mostrar la vista de confirmación de contraseña. Valor por defecto es registration/password_reset_confirm.html.

token_generator

Instancia de la clase para verificar la contraseña. Por defecto utilizará default_token_generator, que es una instancia de django.contrib.auth.tokens.PasswordResetTokenGenerator.

post_reset_login

Booleano indicando si el usuario debe ser autenticado automáticamente después de un reseteo de contraseña exitoso. Por defecto es False.

post_reset_login_backend

Un camino punto con la ruta de acceso al backend de autenticación para utilizar cuando se autentica a un usuario si post_reset_login es True. Requerido solo si tienes múltiples AUTHENTICATION_BACKENDS configurados. Por defecto, es None.

form_class

Formulario que se usará para establecer la contraseña. Por defecto, es SetPasswordForm.

success_url

URL a redirigir después de que se complete el restablecimiento de contraseña. Por defecto, es 'password_reset_complete'.

extra_context

Un diccionario de datos de contexto que se agregarán a los datos de contexto predeterminados pasados al template.

reset_url_token

Parámetro de token mostrado como componente de las URL de restablecimiento de contraseña. Por defecto, es 'set-password'.

Contexto de plantilla:

  • form: El formulario (consulte form_class anterior) para establecer la nueva contraseña del usuario.

  • validlink: Booleano, True si el enlace (combinación de uidb64 y token) es válido o no se ha utilizado aún.

class PasswordResetCompleteView[fuente]

Nombre de URL: password_reset_complete

Presenta una vista que informa al usuario de que la contraseña se ha cambiado con éxito.

Atributos:

template_name

El nombre completo de un template para mostrar la vista. Por defecto, es registration/password_reset_complete.html.

extra_context

Un diccionario de datos de contexto que se agregarán a los datos de contexto predeterminados pasados al template.

Funciones auxiliares

redirect_to_login(next, login_url=None, redirect_field_name='next')[fuente]

Redirecciona a la página de inicio de sesión, y luego vuelve a otra URL después de un inicio de sesión exitoso.

Argumentos obligatorios:

  • next: La URL para redirigirse después de un inicio de sesión exitoso.

Argumentos opcionales:

  • login_url: La URL de la página de inicio de sesión a la que redirigir. Por defecto, se utiliza settings.LOGIN_URL si no se proporciona.

  • redirect_field_name: El nombre de un campo GET que contiene la URL a la que redirigir después del inicio de sesión. Sobreescribe next si se pasa el parámetro GET correspondiente.

Formularios integrados

Si no deseas utilizar las vistas integradas, pero quieres la comodidad de no tener que escribir formularios para esta funcionalidad, el sistema de autenticación proporciona varios formularios integrados ubicados en django.contrib.auth.forms.

Nota

Las formas de autenticación integradas hacen ciertas suposiciones sobre el modelo de usuario con el que están trabajando. Si estás utilizando un modelo de usuario personalizado, puede ser necesario definir tus propias formas para el sistema de autenticación. Para más información, consulta la documentación sobre el uso de las formas de autenticación integradas con modelos de usuarios personalizados.

class AdminPasswordChangeForm[fuente]

Una forma utilizada en la interfaz de administración para cambiar la contraseña de un usuario, incluyendo la capacidad de establecer una contraseña inutilizable (unusable password), lo que impide al usuario iniciar sesión con autenticación basada en contraseña.

Toma al user como el primer argumento posicional.

Opción para deshabilitar (o volver a habilitar) la autenticación basada en contraseña fue agregada.

class AdminUserCreationForm[fuente]

Un formulario utilizado en la interfaz de administración para crear un nuevo usuario. Hereda de UserCreationForm.

Incluye un campo adicional usable_password, habilitado por defecto. Si usable_password está habilitado, verifica que password1 y password2 no estén vacíos y coincidan, valida la contraseña utilizando validate_password(), y establece la contraseña del usuario mediante set_password(). Si usable_password está deshabilitado, no se realiza ninguna validación de contraseña, y la autenticación basada en contraseña está deshabilitada para el usuario llamando a set_unusable_password().

class AuthenticationForm[fuente]

Un formulario para iniciar sesión.

Toma request como su primer argumento posicional, que se almacena en la instancia del formulario para uso por sub-clases.

confirm_login_allowed(user)[fuente]

Por defecto, AuthenticationForm rechaza a los usuarios cuya bandera is_active esté establecida en False. Puedes sobrescribir este comportamiento con una política personalizada para determinar qué usuarios pueden iniciar sesión. Haz esto con un formulario personalizado que herede de AuthenticationForm y sobreescriba el método confirm_login_allowed(). Este método debe levantar una ValidationError si el usuario dado no puede iniciar sesión.

Por ejemplo, para permitir que todos los usuarios inicie sesión independientemente del estado «activo»:

from django.contrib.auth.forms import AuthenticationForm


class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm):
    def confirm_login_allowed(self, user):
        pass

(En este caso, también necesitarás utilizar un backend de autenticación que permita a los usuarios inactivos, como AllowAllUsersModelBackend.)

O para permitir solo algunos usuarios activos iniciar sesión:

class PickyAuthenticationForm(AuthenticationForm):
    def confirm_login_allowed(self, user):
        if not user.is_active:
            raise ValidationError(
                _("This account is inactive."),
                code="inactive",
            )
        if user.username.startswith("b"):
            raise ValidationError(
                _("Sorry, accounts starting with 'b' aren't welcome here."),
                code="no_b_users",
            )
class BaseUserCreationForm[fuente]

Un ModelForm para crear un nuevo usuario. Este es la clase base recomendada si necesitas personalizar el formulario de creación de usuarios.

Tiene tres campos: username (del modelo de usuario), password1, y password2. Verifica que password1 y password2 coincidan, valida la contraseña utilizando validate_password(), y establece la contraseña del usuario mediante set_password().

class PasswordChangeForm[fuente]

Un formulario para permitir que un usuario cambie su contraseña.

class PasswordResetForm[fuente]

Un formulario para generar y enviar un enlace de uso único para restablecer la contraseña de un usuario.

send_mail(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)[fuente]

Utiliza los argumentos para enviar EmailMultiAlternatives. Puede sobrescribirse para personalizar cómo se envía el correo electrónico al usuario. Si decide sobrescribir este método, ten en cuenta el manejo potencial de excepciones levantadas debido a fallas al enviar correos electrónicos.

Parámetros:
  • subject_template_name – el template del asunto.

  • email_template_name – el template del cuerpo del correo electrónico.

  • context – el contexto pasado al subject_template, email_template y html_email_template (si no es None).

  • from_email – la dirección de correo electrónico del remitente.

  • to_email – la dirección de correo electrónico del solicitante.

  • html_email_template_name – el template del cuerpo HTML; por defecto a None, en cuyo caso se envía un correo electrónico en texto plano.

Por defecto, save() pobla el context con las mismas variables que PasswordResetView pasa a su contexto de correo electrónico.

class SetPasswordForm[fuente]

Un formulario que permite al usuario cambiar su contraseña sin tener que ingresar la antigua contraseña.

class UserChangeForm[fuente]

Un formulario utilizado en la interfaz administrativa para cambiar la información y permisos de un usuario.

class UserCreationForm[fuente]

Hereda de BaseUserCreationForm. Para ayudar a prevenir la confusión con nombres de usuario similares, el formulario no permite nombres de usuario que difieren solo en mayúsculas y minúsculas.

Datos de autenticación en plantillas

El usuario actualmente conectado y sus permisos se hacen disponibles en el contexto de la plantilla cuando utilizas RequestContext.

Técnica

Técnicamente, estas variables solo están disponibles en el contexto de la plantilla si utilizas RequestContext y el procesador de contexto 'django.contrib.auth.context_processors.auth' está habilitado. Está en el archivo de configuración generado por defecto. Para más información, consulta los docs de RequestContext.

Usuarios

Al renderizar una plantilla con RequestContext, se almacena en la variable de plantilla {{ user }} el usuario actualmente conectado, ya sea una instancia de User o un usuario anónimo AnonymousUser.

{% if user.is_authenticated %}
    <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
    <p>Welcome, new user. Please log in.</p>
{% endif %}

La variable de contexto del template no está disponible si no se está utilizando un RequestContext.

Permisos

Los permisos del usuario actualmente conectado se almacenan en la variable de template {{ perms }}. Esta es una instancia de django.contrib.auth.context_processors.PermWrapper, que es un proxy amigable con plantillas de los permisos.

Evaluar una búsqueda de atributo simple de {{ perms }} como booleano es un proxy a User.has_module_perms(). Por ejemplo, para comprobar si el usuario conectado tiene algún permiso en la aplicación foo:

{% if perms.foo %}

Evaluar una búsqueda de atributo de dos niveles como booleano es un proxy a User.has_perm(). Por ejemplo, para comprobar si el usuario conectado tiene el permiso foo.add_vote:

{% if perms.foo.add_vote %}

Aquí tienes un ejemplo más completo de la verificación de permisos en una plantilla:

{% if perms.foo %}
    <p>You have permission to do something in the foo app.</p>
    {% if perms.foo.add_vote %}
        <p>You can vote!</p>
    {% endif %}
    {% if perms.foo.add_driving %}
        <p>You can drive!</p>
    {% endif %}
{% else %}
    <p>You don't have permission to do anything in the foo app.</p>
{% endif %}

También es posible buscar permisos mediante declaraciones {% if in %}. Por ejemplo:

{% if 'foo' in perms %}
    {% if 'foo.add_vote' in perms %}
        <p>In lookup works, too.</p>
    {% endif %}
{% endif %}

Gestión de usuarios en el admin

Cuando tengas instalados tanto django.contrib.admin como django.contrib.auth, el admin proporciona una forma conveniente para ver y gestionar usuarios, grupos y permisos. Los usuarios pueden crearse y eliminarse como cualquier modelo Django. Los grupos se pueden crear y los permisos asignarse a usuarios o grupos. También se almacena y muestra un registro de ediciones de usuarios en modelos realizadas dentro del admin.

Crear usuarios

Deberías ver un enlace a «Usuarios» en la sección «Auth» de la página principal de indexación del admin. La página de administración de usuario «Add user» es diferente a las páginas estándar de admin, ya que requiere elegir un nombre de usuario y contraseña antes de permitirte editar el resto de campos del usuario. Alternativamente, en esta página puedes elegir un nombre de usuario y deshabilitar la autenticación basada en contraseña para el usuario.

También es importante tener en cuenta que si deseas que una cuenta de usuario pueda crear usuarios utilizando el sitio administrativo de Django, necesitarás darles permiso para agregar usuarios y cambiarlos (es decir, las «permisos» de «Agregar usuario» y «Cambiar usuario»). Si una cuenta tiene permiso para agregar usuarios pero no para cambiarlos, esa cuenta no podrá agregar usuarios. ¿Por qué? Porque si tienes permiso para agregar usuarios, tienes el poder de crear superusuarios, que pueden entonces, a su vez, cambiar otros usuarios. Por lo tanto, Django requiere permisos de «Agregar» y «Cambiar» como una medida de seguridad ligeramente más estricta.

Ten en cuenta cómo permites a los usuarios gestionar permisos. Si le das a un no superusuario la capacidad de editar usuarios, esto es lo mismo que darles el estatus de superusuario porque podrán elevar los permisos de otros usuarios, incluyéndose a sí mismos.

Cambiar contraseñas

Las contraseñas de usuario no se muestran en el sitio administrativo (ni se almacenan en la base de datos), pero los detalles de almacenamiento de contraseñas se muestran. Incluido en la muestra de esta información es un enlace a una forma de cambio de contraseña que permite a los admins cambiar o desactivar las contraseñas de usuario.