Passwords, as great as they have been, have some setbacks, both for users and developers. Applications users tend to always worry about passwords being stolen by phishing tools, or their passwords being leaked online when used on compromised websites. Aside this, they also have to worry about creating and remembering passwords even in contemporary times when password management tools are prevalent. At the flip side of it, Developers have to worry about all the complications of passing passwords through systems and safely storing them in databases. All these, among others, prompted W3C and FIDO as well as other tech juggernauts such as Google, Mozilla, Microsoft and Yubico to put forward a new authentication paradigm which allows biometric and other cryptographic means to authenticate users. It is aptly known as WebAuthn.
Modern browsers support this awesome technology and there are a couple of its implemetations in various major programming languages and web frameworks. However, this series of tutorials will only focus on implementing it in a Django application using a wonderful django package, django-mfa2 which utilizes python-fido2 under the hood.
The full code for this article can be accessed on
Sirneij
/
django_mfa2_example
A simple fingerprint-based authentication and authorization application using django-mfa2
django_mfa2_example
Fingerprint-based authentication and authorization system in Python (Django). This can be integrated with e-voting systems and other applications that should be very secure.
A walk-through of this repository can be found on dev.to in this tutorial-like article Fingerprint-based authentication and authorization in Python(Django) web applications.
This example application uses Django-mfa2 to implement a password-less fingerprint-based authentication and authorization system. It's live and can be accessed here.
Run locally
- clone this report:
git clone https://github.com/Sirneij/django_mfa2_example.git
- create and activate virtual environment (I used
pipenv
but you can stick with venv
, virtualenv
or poetry
):
pipenv shell
pipenv install
- makemigrations and migrate:
python manage.py makemigrations
python manage.py migrate
- optionally, createsuperuser:
python manage.py createsuperuser
and is live here. In the live version, your username must start with CPE
.
Sirneij / django_mfa2_example
A simple fingerprint-based authentication and authorization application using django-mfa2
django_mfa2_example
Fingerprint-based authentication and authorization system in Python (Django). This can be integrated with e-voting systems and other applications that should be very secure.
A walk-through of this repository can be found on dev.to in this tutorial-like article Fingerprint-based authentication and authorization in Python(Django) web applications. This example application uses Django-mfa2 to implement a password-less fingerprint-based authentication and authorization system. It's live and can be accessed here.
Run locally
- clone this report:
git clone https://github.com/Sirneij/django_mfa2_example.git
- create and activate virtual environment (I used
pipenv
but you can stick withvenv
,virtualenv
orpoetry
):pipenv shell pipenv install
- makemigrations and migrate:
python manage.py makemigrations python manage.py migrate
- optionally, createsuperuser:
python manage.py createsuperuser
Below are the links to other articles in this series:
- Fingerprint-based authentication and Authorization in Python(Django) web applications - Introductory part (This part)
- Fingerprint-based authentication and Authorization in Python(Django) web applications - Second part - The meaty part
- Fingerprint-based authentication and Authorization in Python(Django) web applications - Hacking your way out (Part 3) - Hacking your way out
Please note that we won't be that particular about the looks of the application. In fact, it was built using bootstrap5's example templates. It is assumed you have atleast gone through Django tutorial or are familiar with Django.
Now, let's get started.
Fire up your terminal and navigate or create the directory you will be working on. As for me, I have already created django-mfa-example
and have activated my virtual environment using pipenv.
Install django
and django-mfa2
:
┌──(sirneij@sirneij)-[~/Documents/Projects/django-mfa2-example]
└─$[sirneij@sirneij django-mfa2-example]$ pipenv install django django-mfa2
Create a django project with the name you like. I will stick with django_mfa_example
.
┌──(sirneij@sirneij)-[~/Documents/Projects/django-mfa2-example]
└─$[sirneij@sirneij django-mfa2-example]$ django-admin startproject django_mfa_example .
Notice the .
at the end of the command. This prevents django from creating extra folder to hold the project.
You should now have this file structure:
└── django_mfa2_example/
│ ├──── asgi.py
│ ├──── __init__.py
│ ├──── settings.py
│ ├──── urls.py
│ └──── wsgi.py
├── manage.py
├── Pipfile
├── Pipfile.lock
├── Procfile
Next, scaffold a django application. I call it accounts
. Any name is fine, just prefer that.
┌──(sirneij@sirneij)-[~/Documents/Projects/django-mfa2-example]
└─$[sirneij@sirneij django-mfa2-example]$ python manage.py startapp accounts
Proceed to your project's INSTALLED_APPS
in settings.py
file and append mfa
and accounts.apps.AccountsConfig
to it as shown below:
# django_mfa_example > settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'mfa', #add this for django-mfa2
'accounts.apps.AccountsConfig', #your local app
]
Configure your STATICFILES_DIRS
, and STATIC_ROOT
. Create static
and templates
folders at the root of the application and connect them appropriately in your settings.py
file.
If you are lost, check the code on github to guide you.
In your accounts
app, create a urls.py
file and link it to your project's urls.py
. Also, to use django-mfa2
, you are required to add it to your project's urls.py
.
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include
import mfa
import mfa.TrustedDevice
urlpatterns = [
path('admin/', admin.site.urls),
path('mfa/', include('mfa.urls')), #required to use mfa
path('devices/add/', mfa.TrustedDevice.add,name="mfa_add_new_trusted_device"), #required if you intend adding some devices
path("", include('accounts.urls', namespace='accounts')) #include accounts with namespace
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
This line:
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT)
instructs django to serve the static files during development only or when DEBUG
is True
.
Now, let's add some mfa
specific configurations to our project's settings.py
MFA_UNALLOWED_METHODS=() # Methods that shouldn't be allowed for the user
MFA_LOGIN_CALLBACK="accounts.views.login_user_in" # A function that should be called by username to login the user in session
MFA_RECHECK=True # Allow random rechecking of the user
MFA_RECHECK_MIN=10 # Minimum interval in seconds
MFA_RECHECK_MAX=30 # Maximum in seconds
MFA_QUICKLOGIN=True # Allows quick login for returning users
TOKEN_ISSUER_NAME="django_mfa2_example" #TOTP Issuer name, this should be your project's name
if DEBUG:
U2F_APPID="https://localhost" #URL For U2F
FIDO_SERVER_ID=u"localhost" # Server rp id for FIDO2, it is the full domain of your project
else:
U2F_APPID="https://django-mfa2-example.herokuapp.com" #URL For U2F
FIDO_SERVER_ID=u"django-mfa2-example.herokuapp.com" # Server rp id for FIDO2, it is the full domain of your project
FIDO_SERVER_NAME=u"django_mfa2_example"
MFA_REDIRECT_AFTER_REGISTRATION = 'accounts:index'
MFA_SUCCESS_REGISTRATION_MSG = 'Your keys have successfully been created! You '
Since we would like to make the application production-ready, notice the inclusion of these lines:
if DEBUG:
U2F_APPID="https://localhost" #URL For U2F
FIDO_SERVER_ID=u"localhost" # Server rp id for FIDO2, it is the full domain of your project
else:
U2F_APPID="https://django-mfa2-example.herokuapp.com" #URL For U2F
FIDO_SERVER_ID=u"django-mfa2-example.herokuapp.com" # Server rp id for FIDO2, it is the full domain of your project
If you are going to have a different domain name, edit the else
block accordingly.
To wrap up this part, let's include some basic settings to our accounts
application.
First off, populate accounts/urls.py
with the following:
from django.urls import path
app_name = 'accounts'
urlpatterns = []
app_name = 'accounts'
is necessary since we added namespace='accounts'
in our project's urls.py
file. Nothing spectacular aside that.
It's a best practice to override django's default User
model, therefore open up accounts/models.py
file and paste the following in:
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
display_name = models.CharField(max_length=32)
In the code, we are inheriting from AbstractUser
and appending diaplay_name
field to our User table. To know about the reason I used AbstractUser
and not AbstractBaseUser
, read this Vitor Freitas's article and Michael Herman's Creating a Custom User Model in Django.
To make Django aware of this new user model, proceed to your settings.py
file and add:
AUTH_USER_MODEL = 'accounts.User'
If your application name isn't accounts
and/or your new model isn't User
, change the line above to:
AUTH_USER_MODEL = 'application_name.new_user_model_name'
You can now run migrations to ensure no mistakes have been made.
Note that the complete code for this application is on
Sirneij / django_mfa2_example
A simple fingerprint-based authentication and authorization application using django-mfa2
django_mfa2_example
Fingerprint-based authentication and authorization system in Python (Django). This can be integrated with e-voting systems and other applications that should be very secure.
A walk-through of this repository can be found on dev.to in this tutorial-like article Fingerprint-based authentication and authorization in Python(Django) web applications. This example application uses Django-mfa2 to implement a password-less fingerprint-based authentication and authorization system. It's live and can be accessed here.
Run locally
- clone this report:
git clone https://github.com/Sirneij/django_mfa2_example.git
- create and activate virtual environment (I used
pipenv
but you can stick withvenv
,virtualenv
orpoetry
):pipenv shell pipenv install
- makemigrations and migrate:
python manage.py makemigrations python manage.py migrate
- optionally, createsuperuser:
python manage.py createsuperuser
in case you run into problems.
The next part can be accessed using Fingerprint-based authentication and Authorization in Python(Django) web applications - Second part.
Outro
Enjoyed this article? I'm a Software Engineer and Technical Writer actively seeking new opportunities, particularly in areas related to web security, finance, healthcare, and education. If you think my expertise aligns with your team's needs, let's chat! You can find me on LinkedIn and Twitter.
If you found this article valuable, consider sharing it with your network to help spread the knowledge!
References
- Guide to Web Authentication by Suby Raman of Duo Security
- Creating a Custom User Model in Django by Michael Herman
- How to Implement Multiple User Types with Django by Vitor Freitas
Top comments (0)