Django default authentication supports username and password only. In this tutorial we will setup email authentication which will enable us to login with email and password instead of username.
Since we will be creating our own custom User model, this tutorial is helpful only when you are creating a new project.
Authentication is process by which we identify the users and give them access to specific sections in our websites. In this tutorial, we will also attach specific attributes to users in our website to identify if they are staff users, normal users or administrators.
Common authentication methods used in websites and mobile apps are:
- Email Authentication (email and password)
- Email Authentication with Magic link
- Social signin (login with facebook, google and others)
- Login with mobile phone and OTP
We will cover the first authentication method (Email Authentication) where users will enter email and password to login to our website.
Disclaimer: This tutorial includes best practices and approaches necessary when working in any production grade project. This may seem complicated and unnecessary for beginners. I will try to explain all these points below.
Installing specific python version
It is best practice to pin our project to a specific python version. As we add dependencies and new code in our project, we might encounter issues when the project automatically picks the latest python version. With each version new of python new features are added and sometimes old features are removed or deprecated.
If we specify only python3 as the requirement, the developers could install python3.6, python3.7, python3.8, python3.9, python3.10 or python3.11. When multiple developers are working with multiple python versions, the code changes might become incompatible between python versions.
To fix this, we specify a specific python version and every developer uses the same version. Since multiple projects can have different python version requirement, we need a way to install multiple python versions in our machine.
We are using pyenv for creating specific python version (e.g. python 3.8.0 for this project). More details on using pyenv
We first create the base directory which will contain all our code
|
|
Now, inside django-email-auth
we will configure specific python version.
|
|
This will create .python-version
file in this directory (django-email-auth
). Let's verify that our local python installation is working correctly.
|
|
Now, we have configured a specific python version, the next step would be to configure virtual environment.
Creating virtual environment
We will create virtual environment before setting up the project. As per 12 Factor App dependencies should be declared explicitly. We will make sure every dependency of the project is pinned to specific version (including python too). Virtual environment helps us to separate system level python and it's packages with our project specific packages.
Make sure we are in django-email-auth
directory where we setup python 3.8.0. We are using python inbuilt feature to create a virtual environment in venv
directory.
|
|
After setting up the virtual environment, we will upgrade pip to specific version
|
|
Installing Django
|
|
Since we are using virtual environemnt, this gets installed in venv/lib/python3.8/site-packages/
.
|
|
We will add this specific Django version to a text file so that other developers working on the project know the specific version that we are using. For this, we generally create a requirements.txt file which specifies all the packages and their specific version. All these dependencies can be installed later by using pip install -r requirements.txt
Let's create a new requirements.txt
file in django-email-auth
and add below content.
|
|
Creating demo project
Since we have already created the directory, django-email-auth
, we will create a new project and specify .
so that it doesn't create nested directory
|
|
Below is the directory structure created
.
├── manage.py
├── project
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── requirements.txt
└── venv
├── bin
├── include
├── lib
└── pyvenv.cfg
Project structure
We will be creating all our custom apps inside a specific directory apps
in django-email-auth
. This will help us to organized our project files in a cleaner way. This approach is optional.
Creating custom User model for email instead of username
We will create a new app custom_auth
and a model User
.
mkdir -p apps/custom_auth
venv/bin/django-admin startapp custom_auth apps/custom_auth
Since we have created app inside apps directory, will have to update apps/custom_auth/apps.py
and change name = 'custom_auth'
to name = 'apps.custom_auth'
|
|
We will add this new app to our settings file at project/settings.py
. Find INSTALLED_APPS
in this file and append below code.
# project/settings.py -> INSTALLED_APPS
'apps.custom_auth.apps.CustomAuthConfig'
We create a new user by extending AbstractBaseUser
- we are adding PermissionsMixin as this will provide us out of the box django group and permissions functionality
- is_staff is to identify users who can login to django admin backend
- PermissionsMixin provides is_superuser field which enables admin account. This account will have all the permissions on all models in django
Add below code in custom_auth/models.py
. Below code contains both User
model and UserManager
.
|
|
Add below code in custom_auth/admin.py
. This will enable admin functionality for the User
model which we created earlier.
|
|
Since we have create our own User
model, we will have to configure Django to use our model instead of the default User
model. For this, we add below configuration in project/settings.py
.
# append below code at the end of file project/settings.py
AUTH_USER_MODEL = 'custom_auth.User'
Our new User
model is configured. Now we create migrations.
venv/bin/python manage.py makemigrations custom_auth
Applying all migrations along with the new User
migration.
venv/bin/python manage.py migrate
Create a super user which we will use for login.
venv/bin/python manage.py createsuperuser
Run server and access http://localhost:8000/admin/ to verify
venv/bin/python manage.py runserver
After login, we can access the admin console for User
model http://localhost:8000/admin/custom_auth/user/ and create new users.