django-allauth: регистрация и вход через соцсети
Настройка django-allauth 65.x в Django 6: вход по email, подтверждение почты, VK ID, Яндекс, Telegram, Google и GitHub, headless API, 2FA и шаблоны.
Содержание · 13 разделов
- Что умеет django-allauth и когда он нужен
- Установка
- Настройка settings.py
- Новые настройки вместо устаревших
- URL и миграции
- Регистрация и вход по email без username
- Подтверждение email
- Пользователи, созданные до подключения allauth
- Вход через соцсети: общая схема
- Провайдеры для российской аудитории
- VK ID
- Яндекс ID
- Telegram
- Одноклассники и Mail.ru
- Google и GitHub
- Один пользователь, несколько способов входа
- Headless-режим для SPA и мобильных приложений
- Двухфакторная аутентификация и passkeys
- Кастомизация шаблонов и форм
- Шаблоны
- Дополнительные поля при регистрации
- Адаптер: правила регистрации
- Частые ошибки
- AccountMiddleware must be added to settings.MIDDLEWARE
- SocialApp.DoesNotExist или MultipleObjectsReturned
- redirect_uri mismatch на стороне провайдера
- 404 на /accounts/profile/ после входа
- В админку не входится по username
- Старые пользователи получают письмо с подтверждением
- Лимиты попыток входа не работают на продакшне
- Telegram: Bot domain invalid
- Частые вопросы
- Как закрыть регистрацию, но оставить вход?
- Нужен ли django.contrib.sites для django-allauth?
- Чем django-allauth отличается от dj-rest-auth?
- Как обновиться со старой версии 0.5x?
- Можно ли входить по номеру телефона?
- Итог
django-allauth — пакет для Django, который добавляет к встроенной аутентификации готовую регистрацию, вход по email, подтверждение почты, вход через VK ID, Яндекс, Telegram, Google, GitHub и ещё более сотни провайдеров, двухфакторную аутентификацию и JSON API для SPA и мобильных приложений. Всё это подключается настройками, без своих представлений и форм.
Быстрый ответ: установите django-allauth[socialaccount], добавьте allauth, allauth.account и allauth.socialaccount в INSTALLED_APPS, AccountMiddleware — в MIDDLEWARE, бэкенд allauth.account.auth_backends.AuthenticationBackend — в AUTHENTICATION_BACKENDS, маршрут path("accounts/", include("allauth.urls")) — в urls.py и выполните migrate. Вход по email без username включают две настройки: ACCOUNT_LOGIN_METHODS = {"email"} и ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*", "password2*"]. Все примеры ниже проверены на django-allauth 65.19.7 и Django 6.1.2 (пакет поддерживает Django от 4.2 до 6.1 и Python 3.10–3.14).
Что умеет django-allauth и когда он нужен
Пакет состоит из нескольких Django-приложений. Подключайте только нужные:
| Приложение | Что даёт | Extra для pip |
|---|---|---|
allauth.account | регистрация, вход по username, email или телефону, подтверждение email, сброс и смена пароля, вход по одноразовому коду | — |
allauth.socialaccount | вход через OAuth-провайдеров, привязка нескольких соцсетей к одному аккаунту | socialaccount |
allauth.mfa | двухфакторная аутентификация: TOTP-приложения, резервные коды, ключи и passkeys (WebAuthn) | mfa |
allauth.headless | JSON API тех же сценариев для React, Vue и мобильных приложений | headless |
allauth.usersessions | список активных сессий пользователя с возможностью завершить остальные | — |
Встроенного django.contrib.auth достаточно, если пользователей заводит администратор, а на сайте есть только вход и выход по паролю — это разобрано в статье про аутентификацию в Django. django-allauth нужен, когда посетители регистрируются сами: с ним не придётся писать подтверждение почты, ограничение попыток входа, вход через соцсети и 2FA.
Альтернатива для соцсетей — пакет social-auth-app-django из проекта Python Social Auth. Он умеет только вход через провайдеров: регистрацию по email, подтверждение почты и 2FA придётся писать самостоятельно.
Установка
Ставьте пакет в виртуальное окружение проекта:
# Windows
py -m venv .venv
.venv\Scripts\activate
python -m pip install "django-allauth[socialaccount]"
# macOS и Linux
python3 -m venv .venv
source .venv/bin/activate
python -m pip install "django-allauth[socialaccount]"
Extras можно перечислить через запятую: "django-allauth[socialaccount,mfa,headless]". Без socialaccount пакет установится без библиотек requests, oauthlib и PyJWT, и провайдеры работать не будут. Для mfa дополнительно ставятся qrcode и fido2, для headless — PyJWT.
Совет: закрепите версию в
requirements.txt(django-allauth==65.19.7) и обновляйтесь осознанно: в ветке 65.19 вышло несколько исправлений безопасности, а в release notes бывают изменения, требующие правки настроек.
Настройка settings.py
Минимальная конфигурация для входа по email с обязательным подтверждением почты:
# config/settings.py
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"allauth",
"allauth.account",
"allauth.socialaccount",
# провайдеры — по одному приложению на каждый
"allauth.socialaccount.providers.github",
"allauth.socialaccount.providers.google",
"allauth.socialaccount.providers.vk",
"allauth.socialaccount.providers.yandex",
"allauth.socialaccount.providers.telegram",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"allauth.account.middleware.AccountMiddleware",
]
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend",
]
ACCOUNT_LOGIN_METHODS = {"email"}
ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*", "password2*"]
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
LOGIN_REDIRECT_URL = "/"
LANGUAGE_CODE = "ru"
Что здесь важно:
AccountMiddlewareобязателен с версии 0.56. Без него Django не запустится:ImproperlyConfigured: allauth.account.middleware.AccountMiddleware must be added to settings.MIDDLEWARE. Ставьте его послеAuthenticationMiddleware.- Бэкенд allauth проверяет логин и пароль с учётом
ACCOUNT_LOGIN_METHODSи наследуетModelBackend, поэтому права и группы работают и без него.ModelBackendв списке нужен, если в админку входят по username, а на сайте — по email (подробнее — в разделе об ошибках). - В
TEMPLATESнужен контекст-процессорdjango.template.context_processors.request. В проектах, созданныхstartproject, он уже есть. - Фреймворк сайтов
django.contrib.sitesиSITE_IDбольше не обязательны: без них allauth берёт домен из текущего запроса. Добавляйте их только для нескольких доменов в одном проекте и до первогоmigrate. LANGUAGE_CODE = "ru"переводит страницы и письма allauth на русский — переводы поставляются вместе с пакетом.
Новые настройки вместо устаревших
Большинство русскоязычных инструкций написаны для версий до 65.4 и используют настройки, которые больше не рекомендуются. Они пока работают, но manage.py check выдаёт предупреждения:
| Устаревшая настройка | Замена |
|---|---|
ACCOUNT_AUTHENTICATION_METHOD = "email" | ACCOUNT_LOGIN_METHODS = {"email"} (с 65.4) |
ACCOUNT_AUTHENTICATION_METHOD = "username_email" | ACCOUNT_LOGIN_METHODS = {"email", "username"} |
ACCOUNT_EMAIL_REQUIRED, ACCOUNT_USERNAME_REQUIRED | ACCOUNT_SIGNUP_FIELDS (с 65.5) |
ACCOUNT_SIGNUP_EMAIL_ENTER_TWICE, ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE | поля email2 и password2 в ACCOUNT_SIGNUP_FIELDS |
ACCOUNT_LOGIN_ATTEMPTS_LIMIT, ACCOUNT_LOGIN_ATTEMPTS_TIMEOUT | ACCOUNT_RATE_LIMITS["login_failed"] |
ACCOUNT_EMAIL_CONFIRMATION_COOLDOWN | ACCOUNT_RATE_LIMITS["confirm_email"] |
Так выглядит проверка проекта со старыми настройками — allauth сразу подсказывает замену:
System check identified some issues:
WARNINGS:
?: settings.ACCOUNT_AUTHENTICATION_METHOD is deprecated, use: settings.ACCOUNT_LOGIN_METHODS = {'email'}
?: settings.ACCOUNT_EMAIL_REQUIRED is deprecated, use: settings.ACCOUNT_SIGNUP_FIELDS = ['email*', 'password1*', 'password2*']
?: settings.ACCOUNT_LOGIN_ATTEMPTS_LIMIT/TIMEOUT is deprecated, use: settings.ACCOUNT_RATE_LIMITS['login_failed']
?: settings.ACCOUNT_USERNAME_REQUIRED is deprecated, use: settings.ACCOUNT_SIGNUP_FIELDS = ['email*', 'password1*', 'password2*']
System check identified 4 issues (0 silenced).
URL и миграции
# config/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path("admin/", admin.site.urls),
path("accounts/", include("allauth.urls")),
]
python manage.py migrate
python manage.py runserver
migrate создаёт таблицы account (адреса email и их статус), socialaccount (приложения провайдеров и привязанные аккаунты) и mfa, если оно подключено. django.contrib.auth.urls подключать не нужно: allauth заменяет все его маршруты, а на одном префиксе они будут конфликтовать.
Основные адреса после подключения:
| Адрес | Имя маршрута | Назначение |
|---|---|---|
/accounts/signup/ | account_signup | регистрация |
/accounts/login/ | account_login | вход |
/accounts/logout/ | account_logout | выход (POST-формой) |
/accounts/password/reset/ | account_reset_password | сброс пароля |
/accounts/email/ | account_email | управление адресами email |
/accounts/3rdparty/ | socialaccount_connections | привязанные соцсети |
/accounts/github/login/callback/ | github_callback | адрес возврата от провайдера |
/accounts/2fa/ | mfa_index | настройка 2FA (с allauth.mfa) |
В шаблонах ссылайтесь по именам: {% url 'account_login' %}. Стандартный LOGIN_URL Django равен /accounts/login/, поэтому @login_required сразу ведёт на страницу входа allauth. Старые адреса /accounts/social/... пока работают как перенаправления.
Регистрация и вход по email без username
Вход по email задаёт ACCOUNT_LOGIN_METHODS, а состав формы регистрации — ACCOUNT_SIGNUP_FIELDS. Звёздочка после имени поля делает его обязательным:
ACCOUNT_LOGIN_METHODS = {"email"} # вход только по email
ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*", "password2*"]
# вход по email или username, username при регистрации тоже спрашиваем
# ACCOUNT_LOGIN_METHODS = {"email", "username"}
# ACCOUNT_SIGNUP_FIELDS = ["email*", "username*", "password1*", "password2*"]
Поле password2 — повтор пароля, email2 — повтор email. Если убрать password2*, форма станет короче.
Стандартная модель User требует username. Если его нет в форме, allauth заполнит его сам из адреса: пользователь anna@example.com получит username anna (при совпадении добавится суффикс). Если в вашей модели поля username нет совсем, укажите ACCOUNT_USER_MODEL_USERNAME_FIELD = None — как спроектировать такую модель, описано в статье про свою модель пользователя.
Несовместимые настройки allauth ловит на check. Например, вход по email без email в форме регистрации:
CRITICALS:
?: ACCOUNT_EMAIL_VERIFICATION = 'mandatory' requires 'email*' in ACCOUNT_SIGNUP_FIELDS
WARNINGS:
?: (account.W001) ACCOUNT_LOGIN_METHODS conflicts with ACCOUNT_SIGNUP_FIELDS
Ещё два способа входа включаются одной настройкой:
ACCOUNT_LOGIN_BY_CODE_ENABLED = True— вход по одноразовому коду из письма, без пароля.ACCOUNT_LOGIN_METHODS = {"phone"}— вход по телефону через SMS (с 65.5). Отправку SMS и хранение номера реализуют методы своего адаптера: allauth не знает, где у вас лежит телефон и какой SMS-шлюз вы используете.
Защита от перебора включена по умолчанию: не больше 5 неудачных попыток входа на один аккаунт за 5 минут и 10 в минуту с одного IP. Лимиты меняются словарём ACCOUNT_RATE_LIMITS.
Подтверждение email
ACCOUNT_EMAIL_VERIFICATION принимает три значения:
"none"— письмо не отправляется;"optional"— письмо отправляется, но войти можно и без подтверждения (значение по умолчанию);"mandatory"— пока адрес не подтверждён, войти нельзя.
С "mandatory" сценарий такой: после регистрации пользователь попадает на /accounts/confirm-email/ («Письмо отправлено»), получает письмо со ссылкой /accounts/confirm-email/<ключ>/, открывает её и нажимает кнопку подтверждения. Попытка входа до подтверждения возвращает его на ту же страницу, а письмо отправляется повторно — не чаще раза в 3 минуты.
Полезные настройки:
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 3 # срок жизни ссылки, по умолчанию 3 дня
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True # войти сразу после подтверждения
ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True # код в письме вместо ссылки
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https" # https в ссылках писем на продакшне
По умолчанию ссылка из письма открывает страницу с кнопкой, а подтверждение происходит POST-запросом. Так почтовые сканеры, которые переходят по ссылкам, не подтверждают адрес за пользователя. Подтверждение прямо по GET включает ACCOUNT_CONFIRM_EMAIL_ON_GET = True.
Для разработки письма удобно выводить в консоль. В проекте, созданном startproject в Django 6.1, это уже настроено через MAILERS с консольным бэкендом; в Django 5.2 и 6.0 задайте EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend". Как подключить SMTP для продакшна, показано в статье про аутентификацию в Django.
Пользователи, созданные до подключения allauth
allauth хранит статус адресов в отдельной таблице EmailAddress. У пользователей, созданных раньше (в том числе через createsuperuser), записей там нет, и с "mandatory" при первом входе им придёт письмо с подтверждением. Если адреса заведомо рабочие, отметьте их подтверждёнными в python manage.py shell:
from allauth.account.models import EmailAddress
from django.contrib.auth import get_user_model
for user in get_user_model().objects.exclude(email=""):
EmailAddress.objects.update_or_create(
user=user,
email=user.email.lower(),
defaults={"verified": True, "primary": True},
)
Вход через соцсети: общая схема
Подключение любого OAuth-провайдера состоит из одинаковых шагов:
- Добавьте приложение провайдера в
INSTALLED_APPS:allauth.socialaccount.providers.<id>. - Зарегистрируйте приложение в кабинете разработчика провайдера и укажите адрес возврата (callback, redirect URI) вида
https://example.com/accounts/<id>/login/callback/. Он должен совпадать символ в символ: протокол, домен, порт и завершающий слеш. - Передайте allauth идентификатор и секрет: в
SOCIALACCOUNT_PROVIDERSили в админке (раздел «Социальные аккаунты» → «Приложения социальных сетей»).
Ключи лучше хранить в переменных окружения:
import os
SOCIALACCOUNT_PROVIDERS = {
"github": {
"APP": {
"client_id": os.environ["GITHUB_CLIENT_ID"],
"secret": os.environ["GITHUB_SECRET"],
},
},
"yandex": {
"APP": {
"client_id": os.environ["YANDEX_CLIENT_ID"],
"secret": os.environ["YANDEX_SECRET"],
},
},
}
Выберите один способ хранения для каждого провайдера. Если ключи GitHub есть и в настройках, и в админке, при входе возникнет MultipleObjectsReturned; если их нет нигде — SocialApp.DoesNotExist.
Кнопки входа на странице /accounts/login/ появятся сами. В своём шаблоне выведите весь список провайдеров или отдельную кнопку:
{% load socialaccount %}
{# все подключённые провайдеры #}
{% include "socialaccount/snippets/provider_list.html" with process="login" %}
{# одна кнопка: POST-форма сразу ведёт на сайт провайдера #}
<form method="post" action="{% provider_login_url 'vk' next='/profile/' %}">
{% csrf_token %}
<button type="submit">Войти через VK ID</button>
</form>
Обычная ссылка на /accounts/vk/login/ открывает промежуточную страницу с кнопкой «Продолжить»: переход к провайдеру выполняется только POST-запросом. Это защита от подделки входа с чужих сайтов. Настройка SOCIALACCOUNT_LOGIN_ON_GET = True убирает промежуточную страницу, но ослабляет эту защиту.
Если провайдер вернул email, а email обязателен, аккаунт создаётся автоматически. Если адреса нет (как у Telegram), пользователь увидит короткую форму /accounts/3rdparty/signup/ и введёт его сам.
Провайдеры для российской аудитории
| Провайдер | Приложение в allauth | Где регистрировать приложение | Отдаёт email | Особенности |
|---|---|---|---|---|
| VK ID | providers.vk | кабинет VK ID для бизнеса | да, по запросу scope email | работает через id.vk.ru, PKCE включён |
| Яндекс ID | providers.yandex | oauth.yandex.ru | да | права выбираются при создании приложения |
| Telegram | providers.telegram | бот в @BotFather | нет | нужен публичный домен, /setdomain |
| Одноклассники | providers.odnoklassniki | платформа разработчиков OK | при наличии | нужен ещё публичный ключ key |
| Mail.ru | providers.mailru | — | — | модуль без документации, старый API connect.mail.ru |
VK ID
Провайдер vk работает через VK ID (исправлен и переописан в версии 65.8): авторизация идёт через id.vk.ru по OAuth 2.1 с PKCE. Создайте веб-приложение в кабинете VK ID, укажите базовый домен сайта и доверенный Redirect URL https://example.com/accounts/vk/login/callback/.
SOCIALACCOUNT_PROVIDERS = {
"vk": {
"APP": {
"client_id": os.environ["VK_CLIENT_ID"], # ID приложения
"secret": os.environ["VK_SECRET"], # защищённый ключ
},
},
}
Scope email allauth добавляет сам, когда email обязателен при регистрации. VK объединил вход через «ВКонтакте», «Одноклассники» и Mail.ru в VK ID, поэтому для пользователей этих сервисов обычно достаточно одного провайдера vk.
Яндекс ID
Приложение создаётся на oauth.yandex.ru. Выберите платформу «Веб-сервисы», в Redirect URI укажите https://example.com/accounts/yandex/login/callback/, а в правах доступа — доступ к адресу почты и к логину, имени и фамилии. allauth запрашивает права login:email и login:info. Ключи передаются так же, как для VK, в блоке "yandex".
Частая ошибка из обсуждений — в кабинете указан тестовый адрес https://oauth.yandex.ru/verification_code. Этот адрес служит для ручного получения токена при отладке. С ним Яндекс отклонит вход с сайта с ошибкой о неверном redirect_uri.
Telegram
Вход через Telegram работает без OAuth: пользователь подтверждает вход в виджете, привязанном к вашему боту. Создайте бота в @BotFather и привяжите к нему домен сайта командой /setdomain. В настройках client_id — числовой ID бота (часть токена до двоеточия), secret — полный токен:
SOCIALACCOUNT_PROVIDERS = {
"telegram": {
"APP": {
"client_id": "7000000000",
"secret": os.environ["TELEGRAM_BOT_TOKEN"], # 7000000000:AA...
},
"AUTH_PARAMS": {"auth_date_validity": 30}, # секунд на завершение входа
},
}
Telegram не передаёт email, поэтому с обязательным email пользователь введёт адрес вручную. allauth проверяет подпись данных и их возраст: если часы сервера отстают, вход будет отклонён — включите синхронизацию времени (NTP). localhost бот не примет, для локальной проверки нужен публичный адрес, например туннель.
Одноклассники и Mail.ru
Для Одноклассников кроме client_id и secret укажите в APP публичный ключ приложения "key": без него запрос профиля не подписывается.
Модуль providers.mailru в пакете есть, но страницы в документации allauth у него нет, а работает он через старый API connect.mail.ru. Для новых проектов выбирайте VK ID.
Google и GitHub
Google. В Google Cloud Console настройте экран согласия OAuth (OAuth consent screen), затем в разделе Credentials создайте OAuth client ID типа Web application. В Authorized redirect URIs добавьте http://127.0.0.1:8000/accounts/google/login/callback/ для разработки и адрес продакшна. Включать отдельные API не нужно: права profile и email allauth запросит сам.
GitHub. Settings → Developer settings → OAuth Apps → New OAuth App, поле Authorization callback URL — http://127.0.0.1:8000/accounts/github/login/callback/. У OAuth App GitHub один callback URL, поэтому для разработки и продакшна удобнее завести два приложения. Email allauth получит через право user:email, даже если пользователь скрыл адрес в профиле.
127.0.0.1 и localhost для провайдера — разные адреса. Открывайте сайт по тому же адресу, что указан в кабинете.
Один пользователь, несколько способов входа
Залогиненный пользователь привязывает соцсети на странице /accounts/3rdparty/. Если же человек зарегистрировался по email, а потом нажал «Войти через Google» с тем же адресом, allauth по умолчанию не входит в существующий аккаунт: недобросовестный провайдер мог бы подставить чужой email. Для доверенных провайдеров это меняют настройки:
SOCIALACCOUNT_EMAIL_AUTHENTICATION = True # входить в аккаунт с тем же подтверждённым email
SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True # и сразу привязать соцсеть
Headless-режим для SPA и мобильных приложений
Если интерфейс написан на React, Vue или это мобильное приложение, шаблоны allauth не нужны. Модуль allauth.headless отдаёт те же сценарии — регистрацию, вход, подтверждение email, соцсети и 2FA — в виде JSON API.
python -m pip install "django-allauth[socialaccount,headless]"
# settings.py
INSTALLED_APPS += ["allauth.headless"]
HEADLESS_ONLY = True # отключить HTML-страницы allauth
HEADLESS_FRONTEND_URLS = {
"account_confirm_email": "https://app.example.com/account/verify-email/{key}",
"account_reset_password": "https://app.example.com/account/password/reset",
"account_reset_password_from_key": "https://app.example.com/account/password/reset/key/{key}",
"account_signup": "https://app.example.com/account/signup",
"socialaccount_login_error": "https://app.example.com/account/provider/callback",
}
# config/urls.py
urlpatterns = [
path("admin/", admin.site.urls),
path("accounts/", include("allauth.urls")), # нужен для callback провайдеров
path("_allauth/", include("allauth.headless.urls")),
]
HEADLESS_FRONTEND_URLS — адреса страниц вашего фронтенда: ссылки в письмах будут вести туда вместо /accounts/.... С HEADLESS_ONLY = True страница /accounts/login/ возвращает 404, но маршруты возврата от провайдеров продолжают работать.
API разделено на два клиента:
browser(/_allauth/browser/v1/...) — для SPA в браузере: сессия в cookie и CSRF-токен;app(/_allauth/app/v1/...) — для мобильных и десктопных приложений: токен в заголовкеX-Session-Token.
Регистрация через клиент app:
curl -X POST http://127.0.0.1:8000/_allauth/app/v1/auth/signup \
-H "Content-Type: application/json" \
-d '{"email": "ivan@example.com", "password": "s3cret-Pass-42"}'
Ответ (отформатирован) — 401, потому что email ещё не подтверждён; ожидающий шаг отмечен is_pending:
{
"status": 401,
"data": {
"flows": [
{ "id": "login" },
{ "id": "signup" },
{ "id": "verify_email", "is_pending": true }
]
},
"meta": {
"is_authenticated": false,
"session_token": "jeisdpy9nff3x2z586234eic3z9ydyf2"
}
}
Приложение сохраняет session_token и передаёт его в заголовке X-Session-Token в следующих запросах. Если нужны JWT, переключите стратегию токенов и задайте RSA-ключ — без ключа вход упадёт с ошибкой загрузки PEM:
HEADLESS_TOKEN_STRATEGY = "allauth.headless.tokens.strategies.jwt.JWTTokenStrategy"
HEADLESS_JWT_PRIVATE_KEY = os.environ["JWT_PRIVATE_KEY"] # PEM, RS256 по умолчанию
Тогда ответ на успешный вход содержит access_token (по умолчанию живёт 5 минут) и refresh_token (сутки), а запросы авторизуются заголовком Authorization: Bearer <access_token>.
Свой API на Django REST Framework защищается теми же токенами: в authentication_classes укажите allauth.headless.contrib.rest_framework.authentication.XSessionTokenAuthentication или JWTTokenAuthentication. Для Django Ninja есть класс XSessionTokenAuth в allauth.headless.contrib.ninja.security. Полный список эндпоинтов — в документации allauth, включая спецификацию OpenAPI.
Двухфакторная аутентификация и passkeys
python -m pip install "django-allauth[mfa]"
INSTALLED_APPS += ["allauth.mfa"]
MFA_SUPPORTED_TYPES = ["totp", "recovery_codes", "webauthn"]
MFA_PASSKEY_LOGIN_ENABLED = True # вход по passkey без пароля
# MFA_WEBAUTHN_ALLOW_INSECURE_ORIGIN = True # только для локальной разработки по http
После migrate пользователь включает 2FA на странице /accounts/2fa/: сканирует QR-код в Google Authenticator, Яндекс Ключе или другом TOTP-приложении и сохраняет резервные коды. По умолчанию доступны TOTP и резервные коды; ключи и passkeys (webauthn) включаются явно и работают только по HTTPS. Включить 2FA можно только с подтверждённым email: иначе злоумышленник мог бы зарегистрироваться на чужой адрес и закрыть аккаунт вторым фактором от настоящего владельца.
Вход в админку Django не проходит через allauth: на нём нет ни ограничения попыток, ни 2FA. Перенаправьте его на страницу входа allauth:
# config/urls.py
from allauth.account.decorators import secure_admin_login
from django.contrib import admin
admin.autodiscover()
admin.site.login = secure_admin_login(admin.site.login)
Теперь /admin/login/ ведёт на /accounts/login/?next=/admin/, а пользователь без is_staff получит 403.
Кастомизация шаблонов и форм
Шаблоны
Стандартные шаблоны allauth — голый HTML без стилей. Переопределяйте их файлами с тем же путём в папке шаблонов проекта (TEMPLATES["DIRS"] = [BASE_DIR / "templates"]). Все страницы наследуются от allauth/layouts/base.html, поэтому, чтобы встроить их в дизайн сайта, достаточно одного файла:
{# templates/allauth/layouts/base.html #}
{% extends "base.html" %}
Ваш base.html должен содержать блоки head_title и content — их заполняют страницы allauth. Внешний вид кнопок, полей и форм задают маленькие шаблоны-элементы в allauth/elements/. Например, чтобы все кнопки получили классы Bootstrap:
{# templates/allauth/elements/button.html #}
{% load allauth %}
<button class="btn btn-primary"{% if attrs.type %} type="{{ attrs.type }}"{% endif %}{% if attrs.form %} form="{{ attrs.form }}"{% endif %}>{% slot %}{% endslot %}</button>
Отдельные страницы переопределяются по своим путям: account/login.html, account/signup.html, account/email_confirm.html. Тексты писем лежат в account/email/: письмо после регистрации — email_confirmation_signup_subject.txt и email_confirmation_signup_message.txt. Наследование и блоки разобраны в статье про шаблоны Django.
Дополнительные поля при регистрации
Самый короткий способ — ACCOUNT_SIGNUP_FORM_CLASS. Это обычная форма с методом signup(); её поля добавятся к форме allauth:
# accounts/forms.py
from django import forms
class SignupExtraForm(forms.Form):
first_name = forms.CharField(label="Имя", max_length=150)
def signup(self, request, user):
user.first_name = self.cleaned_data["first_name"]
user.save()
# settings.py
ACCOUNT_SIGNUP_FORM_CLASS = "accounts.forms.SignupExtraForm"
Чтобы полностью заменить форму, наследуйтесь от allauth.account.forms.SignupForm и укажите класс в ACCOUNT_FORMS = {"signup": "accounts.forms.MySignupForm"}.
Адаптер: правила регистрации
Правила регистрации и входа меняют через адаптер. Пример — регистрация только с корпоративной почты:
# accounts/adapters.py
from allauth.account.adapter import DefaultAccountAdapter
from django import forms
class AccountAdapter(DefaultAccountAdapter):
def clean_email(self, email):
email = super().clean_email(email)
if not email.endswith("@company.ru"):
raise forms.ValidationError("Регистрация открыта только для адресов @company.ru")
return email
# settings.py
ACCOUNT_ADAPTER = "accounts.adapters.AccountAdapter"
Для соцсетей есть свой адаптер DefaultSocialAccountAdapter (настройка SOCIALACCOUNT_ADAPTER). Его метод populate_user() позволяет заполнить поля пользователя из данных провайдера.
Частые ошибки
AccountMiddleware must be added to settings.MIDDLEWARE
Django не стартует после обновления allauth со старой версии. Добавьте allauth.account.middleware.AccountMiddleware в MIDDLEWARE после AuthenticationMiddleware.
SocialApp.DoesNotExist или MultipleObjectsReturned
Первая ошибка — для провайдера нет ни блока APP в SOCIALACCOUNT_PROVIDERS, ни записи в админке. Если подключён django.contrib.sites, проверьте ещё, что приложение привязано к сайту с текущим SITE_ID. Вторая ошибка — ключи заданы в обоих местах сразу: удалите один вариант.
redirect_uri mismatch на стороне провайдера
Адрес возврата не совпал с указанным в кабинете. Сравните протокол, домен, порт и завершающий слеш. За nginx сайт часто строит http:// вместо https://: задайте ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https" и SECURE_PROXY_SSL_HEADER, а прокси должен передавать заголовки Host и X-Forwarded-Proto. Пример конфигурации — в статье о деплое на Gunicorn и Nginx.
404 на /accounts/profile/ после входа
Не задан LOGIN_REDIRECT_URL, и Django отправляет на адрес по умолчанию, которого в проекте нет. Укажите LOGIN_REDIRECT_URL = "/" или свою страницу.
В админку не входится по username
При ACCOUNT_LOGIN_METHODS = {"email"} бэкенд allauth не принимает username — даже в форме админки. Либо вводите в поле «Имя пользователя» email, либо оставьте ModelBackend в AUTHENTICATION_BACKENDS, либо подключите secure_admin_login, чтобы в админку входили через страницу allauth.
Старые пользователи получают письмо с подтверждением
У них нет записей в таблице EmailAddress. Создайте их скриптом из раздела о подтверждении email.
Лимиты попыток входа не работают на продакшне
allauth считает попытки в кеше Django. С кешем по умолчанию (LocMemCache) у каждого процесса Gunicorn свой счётчик. Подключите общий кеш — например, Redis.
Telegram: Bot domain invalid
Домен сайта не привязан к боту. Выполните /setdomain в @BotFather и укажите домен, с которого открывается страница входа.
Частые вопросы
Как закрыть регистрацию, но оставить вход?
Переопределите в адаптере метод is_open_for_signup() так, чтобы он возвращал False. Страница /accounts/signup/ покажет «Регистрация закрыта», а новые пользователи не смогут создать аккаунт и через соцсети: социальный адаптер по умолчанию спрашивает решение у обычного. Существующие пользователи входят как раньше.
Нужен ли django.contrib.sites для django-allauth?
Нет. Актуальные версии берут домен из запроса, а приложения провайдеров не требуют привязки к сайту. Фреймворк сайтов нужен, если один проект обслуживает несколько доменов с разными ключами провайдеров или письма отправляются вне запроса, например из Celery.
Чем django-allauth отличается от dj-rest-auth?
dj-rest-auth — набор эндпоинтов Django REST Framework, который для регистрации и соцсетей использует сам allauth. Для нового API на DRF проще взять headless-режим allauth: он поддерживается тем же автором, покрывает 2FA и passkeys и описан спецификацией OpenAPI.
Как обновиться со старой версии 0.5x?
Поднимайте версию и запускайте python manage.py check и migrate. Добавьте AccountMiddleware, если его нет, и замените устаревшие настройки по подсказкам check. Нумерация сменилась в 2024 году: после 0.63 вышла 64.0, так что 65.x — прямое продолжение 0.x. Перед прыжком через несколько версий прочитайте release notes: между ними бывают несовместимые изменения.
Можно ли входить по номеру телефона?
Да, с версии 65.5: ACCOUNT_LOGIN_METHODS = {"phone"} и поле phone* в ACCOUNT_SIGNUP_FIELDS. В своём адаптере реализуйте хранение номера и отправку SMS через выбранный шлюз: готовой интеграции с SMS-сервисами в пакете нет.
Итог
django-allauth закрывает всё, что не входит во встроенную аутентификацию Django: регистрацию с подтверждением email, вход по email без username, соцсети, 2FA и JSON API для фронтенда. Для старта хватит четырёх правок в settings.py, одной строки в urls.py и migrate. Используйте новые настройки ACCOUNT_LOGIN_METHODS и ACCOUNT_SIGNUP_FIELDS. Для российской аудитории подключайте VK ID, Яндекс и Telegram. Ключи провайдеров храните в переменных окружения, а адреса возврата проверяйте символ в символ.
Права, группы и защиту представлений после входа настраивают средствами самого Django. Все материалы по теме собраны в хабе «Аутентификация и права в Django».
- #Django
- #django-allauth
- #Аутентификация
- #OAuth
- #Регистрация