Как изменить Django-Allauth для аутентификации без пароля с использованием JWT и ссылок по электронной почте?

Я пытаюсь изменить Django-Allauth, чтобы разрешить вход в систему и регистрацию без пароля. Когда пользователь пытается зарегистрироваться или войти в систему, на его почтовый ящик должно быть отправлено электронное письмо, содержащее ссылку с токеном JWT. Если токен действителен, пользователь должен пройти проверку подлинности.

Я использую шаблоны Django, но не нашел четкой документации или статей о том, как это реализовать. Как я могу добиться этого, используя Django-Allauth?

Мы были бы очень признательны за любые указания или рекомендации!

Спасибо вам.

я попробовал следующую реализацию с использованием allauth:


# setting.py
ACCOUNT_EMAIL_REQUIRED = True
LOGIN_REDIRECT_URL = "/admin"
ACCOUNT_AUTHENTICATION_METHOD = "email"
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
ACCOUNT_EMAIL_VERIFICATION = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_USER_MODEL_USERNAME_FIELD = None  # Remove `username` field
ACCOUNT_PASSWORD_REQUIRED = False  # Allows empty passwords
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True  # Auto-login after confirmation

ACCOUNT_EMAIL_VERIFICATION = "mandatory"  # Ensures users verify their email
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False


AUTH_USER_MODEL = "users.CustomUser"
ACCOUNT_ADAPTER = "users.adapters.CustomAccountAdapter"
ACCOUNT_FORMS = {
    "signup": "users.forms.CustomSignupForm",
     "login": "users.forms.CustomLoginForm",
}


EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

# forms.py file

from allauth.account.forms import SignupForm
from django import forms


class CustomSignupForm(SignupForm):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if "password1" in self.fields:
            del self.fields["password1"]  # Remove password fields
        if "password2" in self.fields:
            del self.fields["password2"]

    def save(self, request):
        user = super().save(request)
        user.save()
        return user


from allauth.account.forms import LoginForm


class CustomLoginForm(LoginForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if "password" in self.fields:
            del self.fields["password"]  # Remove password field

# adapters.py file
from allauth.account.adapter import DefaultAccountAdapter
from allauth.account.utils import user_email, send_email_confirmation


class CustomAccountAdapter(DefaultAccountAdapter):
    def is_open_for_signup(self, request):
        return True  # Allow signups

    def save_user(self, request, user, form, commit=True):
        user = super().save_user(request, user, form, commit=False)
        if not user.has_usable_password():  # Ensure passwordless login works
            user.set_unusable_password()
        if commit:
            user.save()
        return user

    def send_login_email(self, request, email):
        """
        Instead of asking for a password, send a magic link for login.
        """
        user = self.get_user_by_email(email)
        if user:
            send_email_confirmation(request, user, signup=False)

    def authenticate(self, request, **credentials):
        return None  # Disable password authentication

регистрация заработает, и мне будет отправлено письмо с подтверждением, и когда я нажму на него, он автоматически подтвердит пользователя и войдет в систему

но когда я пытаюсь войти в систему только по электронной почте, чтобы получить электронное письмо, содержащее ссылку для доступа, я получаю следующее:

Ошибка с ключом в /accounts/login/

'password'

Метод запроса:POSTRequest URL:http://127.0.0.1:8000/accounts/login/Django Версия:5.1.5Тип исключения:KeyErrorException Значение:'password 'Exception Location:D:\projects\Django\django-allauth-main\passwordless-auth\.venv\Lib\site-packages\allauth\account\forms.py , строка 156, в user_credentials, созданном во время:allauth.account.views.LoginViewPython Executable:D:\projects\Django\django-allauth-main\passwordless-auth\.venv\Scripts\python.exe

я заглянул внутрь родительской формы LoginForm и обнаружил, что основная реализация формы входа в систему ожидает ввода пароля и не может быть удалена.

итак, я хочу разрешить использование пароля без пароля и изменить электронное письмо, отправляемое пользователю, чтобы включить пользовательский токен jwt.

Переопределите метод user_credentials в вашем пользовательском LoginForm, чтобы исключить поле пароля, и измените LoginView, чтобы отправлять ссылку для входа на основе JWT по электронной почте вместо аутентификации с помощью пароля.

Вернуться на верх