Skip to content
Advertisement

email authentification doesn’t work using django-allauth

I installed django-allauth and set it up to use it for the internet registration and authentication backend in order to have an email confirmation at registration and sign up the users using their email instead of their username.

What is happening is that the registration works perfectly, the authentication using the email doesn’t work whereas it’s working with the username. I got the following error:

The e-mail address and/or password you specified are not correct.

Here my current configuration:

  • Django-allauth: 0.35.0
  • Django: 1.11
  • Python: 3.6.4
  • mysql: 15.1
# settings.py

SITE_ID = 1

DJANGO_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.sites',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
THIRD_PARTY_APPS = [
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
]

AUTHENTIFICATION_BACKENDS = [
        'django.contrib.auth.backends.ModelBackend',
        'allauth.account.auth_backends.AuthenticationBackend',
]
LOGIN_REDIRECT_URL = 'main:home'
LOGOUT_REDIRECT_URL = 'main:home'

TEMPLATES = [
   {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(APPS_DIR, 'templates'),
        ],
        'OPTIONS': {
            'debug': DEBUG,
            'loaders': [
                'django.template.loaders.filesystem.Loader',
                'django.template.loaders.app_directories.Loader',
            ],
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.template.context_processors.media',
                'django.template.context_processors.i18n',
                'django.template.context_processors.static',
                'django.template.context_processors.tz',
                'django.contrib.messages.context_processors.messages',
            ],
       },
    },
]

ACCOUNT_AUTHENTICATION_METHOD = 'username_email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
# url.py

urlpatterns = [
    # Django admin
    url(settings.ADMIN_URL, admin.site.urls),

    url(r'', include('main.urls')),
    url(r'^accounts/', include('allauth.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

I hope I gave all the useful information. I wonder if I missed a configuration issue or if there is a bug somewhere. If you need more information, please let me know, I will gladly provide my help on that matter.

Advertisement

Answer

After some thinking and research, I found a workaround by writing my own adapter as described in the documentation. It consists of rewriting the method save_user().

In order to proceed, you need first to tell your app where is the new adapter by editing the settings.py and adding the following line:

ACCOUNT_ADAPTER = 'yourproject.yourapp.file.classname'

Then create the adapter file such as yourproject/yourapp.file.py, in my case I called the file.py adapter.py and add the following code:

from allauth.account.adapter import DefaultAccountAdapter

class AccountAdapter(DefaultAccountAdapter):

    def save_user(self, request, user, form, commit=True):
        data = form.cleaned_data
        user.email = data.get('email')
        user.username = data.get('email')
        if 'password1' in data:
            user.set_password(data["password1"])
        else:
            user.set_unusable_password()
        self.populate_username(request, user)
        if commit:
            # Ability not to commit makes it easier to derive from
            # this adapter by adding
            user.save()
        return user

Basically, it’s really close to the actual method except I save the email as such as the username in the django system. You will need as well to edit the login.html template if you want to avoid confusion with your user and force the username field to display email.

To avoid any issues related to a malformed email address, you can then add a validator as described in the documentation.

# In validators.py

from django.core.validators import EmailValidator


custom_username_validators = [ASCIIUsernameValidator()]


# In settings.py

ACCOUNT_USERNAME_VALIDATORS = 'some.module.validators.custom_username_validators'
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement