Implementation of authentication system on django
30.10.2023
17.12.2024
9 minutes
113
0
0
0
0
Introduction
Let me start with the question of why a user authentication system is needed at all?
-
Authentication is needed for something like this:
- Provide exclusive opportunities and access to previously closed site features. For example, commenting.
- Collect a database of your clients, who are already loyal to you
- Be constantly in touch with users. You can send them email newsletters or website notifications.
It is important to have an authentication system on your website, if only because this way you will expand your network of clients/friends/partners/readers/customers (underline what is appropriate)
Let me make a reservation right away that the authentication system that you and I will write is not based on the built-in Django application, django.contrib.auth. This will be a separate application with a separate model for it. We will create a simple and understandable authorization system, based on anonymous browser session keys.
Let's get down to business.. Implementing user registration and authentication in Django is not difficult, although it requires specific skills. To begin with, we need a project we will implement user authentication system for .
Here is the finished basic project.
Or a link to the repository on github
And if you still haven’t skipped to the finished solution, please follow me.
How session key authentication works
Now, so that you understand what I will write about , I need to explain how sessions generally work in django and how we can use them to create users.
A session is a small file generated by the server that stores information about the user. This file remains on the server so that the server knows who it is communicating with.
By user we mean the browser.
The process of communication between the user and the server

I talk more about sessions in django in the chapter setting up views in django
Setting up scripts and jQuery
Let's say you have your own website on which you need to implement an authentication system. To create a login page and a registration page. The question arises, where to start? I suggest starting with writing ajax requests.
But before that, let's create the appropriate directories for storing scripts and connect these scripts to our templates. Let's put you now in the Auth application folder. Then:
mkdir -p static/Auth/js;
cd static/Auth/js;
touch on_signup.js; touch on_signin.js;
In the signup.html template, insert it at the very end before {% endblock %}
In the login.html template, do the same thing, just insert
Now that everything you need has been pre-configured, you can move on to the essence or how to make this ajax request work.
Ajax request for registration
The most important thing is at the very beginning. Code of the previously connected script on_signup.js
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
function OnSignup(){
var form_data = new FormData();
form_data.append("csrfmiddlewaretoken", csrftoken);
form_data.append("username", $("#username").val())
form_data.append("email", $("#email").val())
form_data.append("password", $("#password").val())
form_data.append("repassword", $("#repassword").val())
$.ajax({
type: "POST",
url: "/signup/verify/",
data: form_data,
processData: false,
contentType: false,
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin', // Do not send CSRF token to another domain.
success: function(result) {
$("#common-error").removeClass('error success')
$("#common-error").addClass('success')
$("#common-error").text(result.common)
setTimeout(function(){
window.location.href = '/'
},3000)
},
error: function(jqXHR, textStatus, errorThrown){
$("#common-error").removeClass('error success')
$("#common-error").addClass('error')
$("#common-error").text(jqXHR.responseJSON.common)
}
});
}
$(document).ready( function(){
$("#signup").on('click',OnSignup)
})
Now let's deal with it in order.
What is csrftoken? CSRF token (Cross-Site Request Forgery) is a unique server-generated string. It allows you to protect yourself from hackers faking requests to the server for unauthorized access to site user resources.
In order for the form to be sent using the POST method, this token must be transferred to the server through a request.
Next, we collect data from the completed form and save it into a form object which we will send to the server.
var form_data = new FormData();
form_data.append("csrfmiddlewaretoken", csrftoken);
form_data.append("username", $("#username").val())
form_data.append("email", $("#email").val())
form_data.append("password", $("#password").val())
form_data.append("repassword", $("#repassword").val())
We define the method for sending, the address at which we will contact the server. You need to remember it, because you will need to create the appropriate function to process this address.
Next, we define the behavior of our script. When the code returns 200, meaning the user has successfully registered, we will add a caption above the form and redirect him to the main page.
success: function(result) {
$("#common-error").removeClass('error success')
$("#common-error").addClass('success')
$("#common-error").text(result.common)
setTimeout(function(){
window.location.href = '/'
},3000)
},
If it fails, that is, if the code is returned 406 (in my case), we will give a completely different message to the user. So that he corrects the identified errors.
error: function(jqXHR, textStatus, errorThrown){
$("#common-error").removeClass('error success')
$("#common-error").addClass('error')
$("#common-error").text(jqXHR.responseJSON.common)
}
Well, in the end, as I’m already used to, I set up the appropriate events. In this case, pressing the Singup button.
Ajax login request
It’s the same technique, only for confirmation, that is, entry to the site.
And here a little less data will be sent than during registration
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
function OnSignin(){
var form_data = new FormData();
form_data.append("csrfmiddlewaretoken", csrftoken);
form_data.append("username", $("#username").val())
form_data.append("password", $("#password").val())
$.ajax({
type: "POST",
url: "/login/verify/",
data: form_data,
processData: false,
contentType: false,
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin',
success: function(result) {
$("#common-error").text(result.common)
setTimeout(function(){
$("#common-error").removeClass('error success')
$("#common-error").addClass('error')
window.location.href = '/'
},3000)
},
error: function(jqXHR, textStatus, errorThrown){
$("#common-error").removeClass('error success')
$("#common-error").addClass('error')
$("#common-error").text(jqXHR.responseJSON.common)
}
});
}
$(document).ready( function(){
$("#signin").on('click',OnSignin)
})
Create and configure django user model
Now that you have working ajax requests, you need to make an appropriate model for the user.
In the models.py file add:
from django.db import models
from django.template.defaultfilters import slugify
from django.urls import reverse
class Users(models.Model):
name = models.CharField(max_length=256, unique=True)
slug = models.SlugField(max_length=256, unique=True)
email = models.EmailField(blank=False, unique=True)
password = models.CharField(max_length=256, blank=False)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse(type, kwargs={"slug": self.slug})
def save(self, *args, **kwargs):
if not self.pk:
# Newly created object, so set slug
self.slug = slugify(self.name)
super(Users, self).save(*args, **kwargs)
Don't forget to apply migrations to the database
./manage.py makemigrations
./manage.py migrate
Setting up views
Now you have a user model, scripts for sending requests to the server, templates, styles. After all, the site that based on django. What else do we need? I left the most important thing for later, namely validation, authentication and authorization of users. All this happens on the server. I added 3 more paths to urls.py in the Auth application. In total, your Auth/urls.py should look something like this:
from django.urls import path
from .views import login, signup, logout, login_verify, signup_verify
urlpatterns = [
path('login/', login, name='login'),
path('signup/', signup, name='signup'),
path('logout/', logout, name='logout'),
path('login/verify/', login_verify),
path('signup/verify/', signup_verify),
]
Now let's look at each of them separately. Let's discuss all the nuances, so to speak.
Registration view
If we describe this function in general, then it is a set of a wide variety of checks. Such as password length, email address format compliance, and others. And if all checks are passed, a user is created.
def signup_verify(request):
data = {
'common': ' | '
}
status = 200
if request.method == 'POST':
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
repeated_password = request.POST['repassword']
if len(username) == 0:
data['common'] += '⚠ user field is empty | '
status = 406
if len(email) == 0:
data['common'] += '⚠ email is empty | '
status = 406
if len(password) == 0:
data['common'] += '⚠ password is empty | '
status = 406
# Check if user already exist
if Users.objects.filter(name=username).exists() or Users.objects.filter(slug=slugify(username)).exists():
data['common'] += '⚠ user with such name already exist | '
status = 406
# Check if email already used
if Users.objects.filter(email=email).exists():
data['common'] += '⚠ this email already in use | '
status = 406
# Check if username's length is big enough
if len(username) < 3:
data['common'] += '⚠ too short user name | '
status = 406
# Check if username's length not to big
if len(username) > 25:
data['common'] += '⚠ too long user name | '
status = 406
# Check if password length is big enough
if len(password) < 6:
data['common'] += '⚠ too short password | '
status = 406
# Password does not match
if password != repeated_password:
data['common'] += '⚠ passwords mismatch | '
status = 406
# Email addres does not right
if not re.fullmatch(regex, email):
data['common'] += '⚠ email formant are not correct | '
status = 406
if status == 200:
data['common'] = '✔ you have successfully sign up | '
user = Users(name=username, email=email, password=password)
user.save()
return JsonResponse(data, status=status)
else:
status = 403
data['common'] = "Allowed only POST request"
return JsonResponse(data, status=status)
Login view
The login function is also a bunch of checks for the correctness of the entered data. Except that we create additional variables in the current session, such as is_auth and username. And if all the entered data is correct, the function will return the corresponding message and code.
def login_verify(request):
data = {
'common': ' | ',
}
status = 200
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
# username,email,password fields does not filled up
if len(username) == 0:
data['common'] += '⚠ user name field is empty | '
status = 406
if len(password) == 0:
data['common'] += '⚠ password field is empty | '
status = 406
# Check if user already exist
required_user = Users.objects.filter(name=username)
if required_user.exists():
# Password does match
if required_user.first().password == password:
status = 200
request.session["is_auth"] = True
request.session["username"] = username
data['common'] = '✔ You have successfully sign in, redirecting ... '
else:
data['common'] = '⚠ Wrong password'
status = 406
else:
data['common'] = '⚠ No such user in database'
status = 406
return JsonResponse(data, status=status)
Logout view
def logout(request):
request.session.flush()
return HttpResponseRedirect("/")
Everything is quite simple here. We tell the server to clear (forget) about the current session with the user, and then redirect to the main one.
Authentication Use Case
Now that our site can register new users and detect the entry of existing ones, a question arises. What exactly should we do next?
Firstly, I suggest changing the login label to logout. To do this, we modify our home page. In home.html Instead
Login
Secondly, I propose to display the name and email of our user.
Insert this piece of template after the last element of the list
{% if request.session.is_auth %}
{% endif %}
And in Main/views.py the home function will need to be improved
from django.shortcuts import render
from Auth.models import Users
def home(request):
user = Users.objects.filter(name=request.session.get('username', 'Guest')).first()
context = {
'user': user,
}
return render(request, 'Main/home.html', context=context)
First we imported the Users model. Then we find the user using the value we saved earlier in the session,a username. We received it during logging, if you haven't forgotten yet.
After reloading the page and logging in, you will be redirected to the main page and see something like this

This is the basic application of an authentication system. There's still a lot you can do with this. For example, create a separate page for each user or provide the ability to comment. But this is beyond the scope of this article. My goal was to show you how you can implement a user authentication system yourself in django, and it’s up to you to decide how to use it.
Conclusions
Now, you have everything you need to create your own user registration and authorization forms. It wasn't difficult, was it? Although, if you are not used to it, it may seem otherwise. To summarize.
-
Losses:
- You wasted 30 minutes of your life.
- Approximately 100 Mb of hard disk space
-
Acquisitions:
- We learned, studied and most importantly tried to use sessions and cookies in practice
- Django application and skills to connect it to your project
- Purchased templates and scripts that can be referenced and which can be used as a basis for your own
- Update content on the page without reloading it
- Skills in writing templates and forms for registration and authorization
- Ability to process ajax requests in python
- Ability to create ajax requests, POST and GET
I hope the time spent was well spent. And you learned something for yourself.
For those looking for a ready-made solution
Here is a link to download thefinished Django application.
Or a link to download the entire Django project.
Or if you don’t want to mindlessly download files from unknown sites, here is a link to the github repository.
If you decide to download the application, congratulations, you grasp the main feature of django, namely its modularity. This is how you can connect it to your site.
Add the application to settings.py
INSTALLED_APPS = [
'Auth.apps.AuthConfig'
]
In urls.py at the project level, connect routes.
urlpatterns += (
path('', include('Auth.urls')),
)
Everything is ready and configured.
Materials used and useful resources
- How to upload files
- How to send a ajax request
- Events in jQuery
- Manipulation of page elements
- Using crfs-token with django
- A good start for those just starting out
Comments
(0)
Send
It's empty now. Be the first (o゚v゚)ノ
Other
Used termins
- Django views ⟶ In Django, views are a fundamental component that handle the logic of your web application. They process incoming web requests, interact with models (to retrieve or modify data), and return an HTTP response. In essence, views determine what data gets displayed and how it is presented by associating URLs with Python functions or classes.
- Django framework ⟶ Is a high-level, open-source web framework for building web applications using the Python programming language. It follows the model-view-template (MVT) architectural pattern and is designed to facilitate rapid development while promoting clean, pragmatic design.
- Django migrations ⟶ Are a way of propagating changes made to your Django models (which represent your database schema) into the actual database schema. They are a core part of Django's ORM (Object-Relational Mapping) system and help you manage the database schema in a versioned and structured manner.
- Django middleware ⟶ Is a way to process requests globally before they reach the view or after the view has processed them. Middleware is a framework of hooks into Django's request/response processing and is used for several purposes.
- Website ⟶ Is defined as a collection of related web pages that are typically identified by a common domain name and published on at least one web server. Websites can serve various purposes and can include anything from personal blogs to business sites, e-commerce platforms, or informational resources.
Related questions
- I can’t stand Django template language. Do I have to use it? I think this template engine is the best thing ever, but I know that choosing a template language runs close to religion. There’s nothing about Django that requires using the template language, so if you’re attached to Jinja2, Mako, or whatever it's ok.
- Do you offer SEO services? No. Not yet. You see, website promotion is a long process, and I don’t have much experience in promotion. 2 sites in total. Even if my experience was more significant, I don’t think that I would offer comprehensive services for website promotion. Perhaps some measurable work and services. By type of guest posting or earning links.
- How can I see the raw SQL queries Django is running? Make sure your Django DEBUG setting is set to True. Then import connection from django.db. connection.queries is only available if DEBUG is True. It’s a list of dictionaries in order of query execution. Each dictionary has the sql and time property.