🔐 Authentication
Editors log in to the admin with their username and password, like in the
classic Django admin. Content Studio handles the sessions itself and is
configured entirely through the CONTENT_STUDIO setting, so it never
interferes with the authentication your project uses elsewhere.
Who can log in
Only active staff users can log in, and every request checks this again: deactivating a user or revoking their staff status ends their access immediately. What an editor may see and do is decided by the permission hooks.
Sessions
- Short-lived. A session stays active for an hour at a time
(
TOKEN_LIFETIME) and renews itself while the editor works. After a week without using the admin, the editor logs in again (REFRESH_TOKEN_LIFETIME). - Survives a reload. Reloading the page keeps the editor logged in.
- Ends everywhere on a password change. Changing or resetting a password logs the user out on every device.
- Logging out ends the session in that browser.
Sessions are signed with your SECRET_KEY, or with
TOKEN_SIGNING_KEY when you set one.
Login backends
The login backend decides how editors log in. The built-in
UsernamePasswordBackend checks the username and password, like the classic
Django admin. Login attempts are limited per IP address
(LOGIN_THROTTLE_RATE).
# mysite/settings.py
CONTENT_STUDIO = {
"LOGIN_BACKENDS": [
"content_studio.login_backends.UsernamePasswordBackend",
],
}
Only the built-in login backend and token backend
(TOKEN_BACKEND) are supported. Custom
backends, such as single sign-on, are not supported.
Password reset
The content_studio.contrib.password_reset app lets editors reset a
forgotten password with a code sent by email.
-
Add the app to
INSTALLED_APPS:# mysite/settings.pyINSTALLED_APPS = [# ..."content_studio","content_studio.contrib.password_reset",] -
Include its URLs under the admin's prefix:
# mysite/urls.pyfrom django.urls import include, pathurlpatterns = [path("admin/", include("content_studio.contrib.password_reset.urls")),path("admin/", include("content_studio.urls")),] -
Configure Django's
EMAIL_*settings, so the code emails can be sent.
An editor requests a code for their email address, enters it, and sets a new password. How the flow protects itself:
- Only active staff users can reset their password. The email address matches regardless of case; an address shared by several users gets no code.
- Codes have six digits and are valid for 10 minutes
(
PASSWORD_RESET_EXPIRATION_TIME). - Five wrong codes lock the email address out for an hour, also when new codes are requested in between.
- Requests are limited per IP address
(
PASSWORD_RESET_THROTTLE_RATE). - The new password must pass your project's
AUTH_PASSWORD_VALIDATORS. - Unknown addresses and wrong codes get the same answer, so the flow does not reveal which addresses have an account.
The emails are sent as a Django task.
Without a task backend, Django runs the task during the request. Configure
a backend that runs tasks in a worker (the TASKS setting) and the request
only queues the email: it then takes as long for an unknown address as for a
known one, so its duration does not reveal which addresses exist either.
On Django 5.2, which has no tasks framework, the
django-tasks package is used when
installed; otherwise the email is sent during the request.