How to Modify Django-Allauth for Passwordless Authentication Using JWT and Email Links?

I am trying to modify Django-Allauth to allow login and registration without a password. When a user attempts to register or log in, an email should be sent to their inbox containing a link with a JWT token. If the token is valid, the user should be authenticated.

I am using Django templates but haven't found clear documentation or articles on how to implement this. How can I achieve this using Django-Allauth?

Any guidance or references would be greatly appreciated!

Thank you.

i tried the following implementation using 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

the registration work will and sent confirmation mail and when i click it it verify the user and login automatically

but when i try to login only by the email to receive the email that contain the access link i got the following :

KeyError at /accounts/login/

'password'

Request Method:POSTRequest URL:http://127.0.0.1:8000/accounts/login/Django Version:5.1.5Exception Type:KeyErrorException Value:'password'Exception Location:D:\projects\Django\django-allauth-main\passwordless-auth\.venv\Lib\site-packages\allauth\account\forms.py, line 156, in user_credentialsRaised during:allauth.account.views.LoginViewPython Executable:D:\projects\Django\django-allauth-main\passwordless-auth\.venv\Scripts\python.exe

i looked inside LoginForm parent i found that the main implementation of the LoginForm are waiting for password and cannot be discarded.

so i want to allow passwordless and modify the email that are sent to user to include custom jwt token.

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