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'