Django — email user authenthication
By: Mihai Corciu
Tags: Django Allauth, Django, Email Authentication

Initiate a python virtual environment and start a new project:

python -m venv env

source env/bin/activate

pip install Django

pip install django-crispy-forms # for nice forms

mkdir email_auth

cd email_auth

django-admin startproject src .

python manage.py startapp accounts

python manage.py runserver

Update /src/settings.py

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'crispy_forms',

'accounts',

]

...

AUTH_USER_MODEL = 'accounts.CustomUser'

Update ‘/accounts/models.py’

Update ‘/accounts/forms.py’

Update ‘/src/admin.py’

Run:

python manage.py makemigrations

python manage.py migrate

python manage.py createsuperuser

At this point we, in Django-custom user authentication , have to proceed to design templates, views and urls for Django ‘auth’ modules. Instead, we are going to use django-allauth.

pip install django-allauth

Update ‘src/settings.py’

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles', 'django.contrib.sites',

'allauth',

'allauth.account',

'allauth.socialaccount', 'crispy_forms',

'accounts',

] EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'



AUTHENTICATION_BACKENDS = (

# Needed to login by username in Django admin, regardless of `allauth`

"django.contrib.auth.backends.ModelBackend",



# `allauth` specific authentication methods, such as login by e-mail

"allauth.account.auth_backends.AuthenticationBackend",

)



SITE_ID = 1



ACCOUNT_EMAIL_REQUIRED = True

ACCOUNT_USERNAME_REQUIRED = False

ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False

ACCOUNT_SESSION_REMEMBER = True

ACCOUNT_AUTHENTICATION_METHOD = 'email'

ACCOUNT_UNIQUE_EMAIL = True

Run

python manage.py migrate

Update ‘/src/urls.py’

from django.contrib import admin

from django.urls import path, include urlpatterns = [

path('admin/', admin.site.urls),

path('accounts/', include('allauth.urls')),

]

Now we can access page ‘http://127.0.0.1:8000/accounts/login/’ which does not have a pretty template and after login we are redirected to url ‘/accounts/profile’ which is not defined so we have do design templates for login and logout procedures and a home page to redirect instead of ‘/accounts/profile’.

First, update ‘/src/settings’ in order to acces root templates directory:

TEMPLATES = [

{

...

'DIRS': [str(BASE_DIR.joinpath('templates'))],

...

},

]

...

LOGIN_REDIRECT_URL = 'home'

LOGOUT_REDIRECT_URL = 'home'

create ‘/templates/home.html’ (reverse links ‘account_logout’, etc are defined in django-allauth docs)

Update ‘/src/urls.py’:

urlpatterns = [

path('admin/', admin.site.urls),

path('accounts/', include('allauth.urls')),

path('', include('accounts.urls')),

]

Create ‘/accounts/urls.py’

from django.urls import path

from . import views urlpatterns = [

path('', views.home, name = 'home'),

]

And ‘/accounts/views.py’

from django.shortcuts import render def home(request):

return render(request, 'home.html', {})

Now, home page is accesible at ‘localhost:8000’.

The project works with default django-allauth templates if there is no correspondig template create in ‘/email_auth/templates/accounts’ project directory. In order to direct customize this files, download the source of django-allauth and copy ‘django-allauth-master/allauth/templates/account’ to ‘/email_auth/templates/accounts’.

We coud add a some ‘style’ by adding Bootstrap 4 necessary file to base.html and adjusting forms (that mean all {{ form.as_p }} fields from the templates which are not equal in length) to {{ form|crispy }}

A string search in ‘/templates/account/’:

grep 'form.as_p' `find . -type f -name "*.*"` | less

return us the templates which needs adjusting the forms:

./email.html: {{ form.as_p }}

./login.html: {{ form.as_p }}

./password_change.html: {{ form.as_p }}

./password_reset.html: {{ form.as_p }}

./password_reset_from_key.html: {{ form.as_p }}

./password_set.html: {{ form.as_p }}

./signup.html: {{ form.as_p }}

base.html will be like that:

and signup.html like that

Resources: