Django-Admin.ru

django-allauth: регистрация и вход через соцсети

Настройка django-allauth 65.x в Django 6: вход по email, подтверждение почты, VK ID, Яндекс, Telegram, Google и GitHub, headless API, 2FA и шаблоны.

Редакция Django-Admin.ru
· 21 мин чтения

Содержание · 13 разделов
  1. Что умеет django-allauth и когда он нужен
  2. Установка
  3. Настройка settings.py
  4. Новые настройки вместо устаревших
  5. URL и миграции
  6. Регистрация и вход по email без username
  7. Подтверждение email
  8. Пользователи, созданные до подключения allauth
  9. Вход через соцсети: общая схема
  10. Провайдеры для российской аудитории
  11. VK ID
  12. Яндекс ID
  13. Telegram
  14. Одноклассники и Mail.ru
  15. Google и GitHub
  16. Один пользователь, несколько способов входа
  17. Headless-режим для SPA и мобильных приложений
  18. Двухфакторная аутентификация и passkeys
  19. Кастомизация шаблонов и форм
  20. Шаблоны
  21. Дополнительные поля при регистрации
  22. Адаптер: правила регистрации
  23. Частые ошибки
  24. AccountMiddleware must be added to settings.MIDDLEWARE
  25. SocialApp.DoesNotExist или MultipleObjectsReturned
  26. redirect_uri mismatch на стороне провайдера
  27. 404 на /accounts/profile/ после входа
  28. В админку не входится по username
  29. Старые пользователи получают письмо с подтверждением
  30. Лимиты попыток входа не работают на продакшне
  31. Telegram: Bot domain invalid
  32. Частые вопросы
  33. Как закрыть регистрацию, но оставить вход?
  34. Нужен ли django.contrib.sites для django-allauth?
  35. Чем django-allauth отличается от dj-rest-auth?
  36. Как обновиться со старой версии 0.5x?
  37. Можно ли входить по номеру телефона?
  38. Итог

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.headlessJSON 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_REQUIREDACCOUNT_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_TIMEOUTACCOUNT_RATE_LIMITS["login_failed"]
ACCOUNT_EMAIL_CONFIRMATION_COOLDOWNACCOUNT_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-провайдера состоит из одинаковых шагов:

  1. Добавьте приложение провайдера в INSTALLED_APPS: allauth.socialaccount.providers.<id>.
  2. Зарегистрируйте приложение в кабинете разработчика провайдера и укажите адрес возврата (callback, redirect URI) вида https://example.com/accounts/<id>/login/callback/. Он должен совпадать символ в символ: протокол, домен, порт и завершающий слеш.
  3. Передайте 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 IDproviders.vkкабинет VK ID для бизнесада, по запросу scope emailработает через id.vk.ru, PKCE включён
Яндекс IDproviders.yandexoauth.yandex.ruдаправа выбираются при создании приложения
Telegramproviders.telegramбот в @BotFatherнетнужен публичный домен, /setdomain
Одноклассникиproviders.odnoklassnikiплатформа разработчиков OKпри наличиинужен ещё публичный ключ key
Mail.ruproviders.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
  • #Регистрация
↑ ↓ выборEnter открытьEsc закрыть