
Make login and registration forms using Django
16.10.2023
25
0
0
0
0
Task
Implement a user authentication system. For this purpose, a registration form and login form are created on the website timthewebmaster.com.
The registration form must contain the following elements:
- user name ( required )
- user email ( required )
- password ( required )
- repeat password ( required )
- field about the user himself
- user avatar
- registration buttons
The login form should consist of only two fields:
- user name
- password
There should also be a button that would allow you to exit the authenticated user mode.
Solution
Including jQuery to pages templates
For solving such case I need to include one JS library jQuery . This is a popular and simple library. And I need to change security settings of website developed on django. That means change a little bit of settings.py
Setup django for register new users
If be honest it is a not necessary step. But for security sake and for to be sure none of the hackers couldn’t broke up database of server and gain access to credentials of users.
In a file settings.py just add:
CSRF_USE_SESSIONS = True
In the app that main goal to register an user, open urls.py and add 2 more paths.
from django.urls import path
from .views import signup, signup_verify
urlpatterns = [
…
# Это путь на страницу которая будет видна пользователю
path('signup/', signup, name='signup'),
# Это путь/адрес который мы будем использовать чтобы общаться с сервером
path('signup/verify-signup/', signup_verify, name='signup_verify'),
]
Let’s create ajax request for user registration
Now it is a time of JS-script with POST request.
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("repeated_password", $("#repeated_password").val())
form_data.append("about", $("#about").val())
form_data.append("file", document.getElementById('file').files[0]);
$.ajax({
type: "POST",
// Path that we describe in urls.py
url: "verify-signup/",
// Which data to send
data: form_data,
processData: false,
contentType: false,
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin',
// Function that gonna be execute if code eaqual 200
success: function(result) {
$(".hint-required").css("color","green")
$("#common-error").text(result.common)
$("#username-error").text(result.username)
$("#email-error").text(result.email)
$("#password-error").text(result.password)
$("#repassword-error").text(result.password)
// Function that gonna be execute if code eaqual 200
setTimeout(function(){
window.location.href = '/login/'
},3000)
},
// Function that gonna be executed if error accure
error: function(jqXHR, textStatus, errorThrown){
$(".hint-required").css("color","red")
$("#common-error").text(jqXHR.responseJSON.common)
$("#username-error").text(jqXHR.responseJSON.username)
$("#email-error").text(jqXHR.responseJSON.email)
$("#password-error").text(jqXHR.responseJSON.password)
$("#repassword-error").text(jqXHR.responseJSON.password)
}
});
}
// Document ready and loaded
$(document).ready( function(){
$("#signup").on('click',OnSignup)
})
If successful, that is, if all checks are passed, such as password length or existing email, I will give a feedback and redirect to the login page.
If unsuccessful, I will notify the user about this too.
Write down function to register new user to mysql database
In the pre-configuration chapter, we imported the signup_verify function in urls.py, let's define it
from django.shortcuts import render
from django.http import JsonResponse, HttpResponseRedirect
from django.template.defaultfilters import slugify
import re
from MyBlog import settings
from .models import User
...
def signup_verify(request):
message = {
'common': '',
'username': 'обязательно',
'email': 'обязательно',
'password': 'обязательно',
'repassword': 'обязательно',
}
status = 200
# We will only process POST requests
if request.method == 'POST':
# General mail pattern for comparison
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
# We collect the data that was sent
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
repeated_password = request.POST['repeated_password']
about = request.POST['about']
avatar = None
try:
avatar = request.FILES['file']
except:
avatar = None
message['common']='✖ I can't register a new user'
# Name, email, password are empty
if len(username) == 0:
message['username']='⚠user field is empty'
status = 406
if len(email) == 0:
message['email']='⚠ email field is empty'
status = 406
if len(password) == 0:
message['password']='⚠ password field is empty’
status = 406
# Checking if the user already exists
if User.objects.filter(name=username).exists() or User.objects.filter(slug=slugify(username)).exists():
message['username']='⚠a user with the same name already exists'
status = 406
# User already exist
if User.objects.filter(email=email).exists():
message['email']='⚠This email is already in use'
status = 406
if len(username) < 3:
message['username']='⚠the entered name is too short'
status = 406
if len(username) > 25:
message['username']='⚠ the entered name is too long'
status = 406
# Check if password is long enough
if len(password) < 6:
message['password']='⚠the entered password is too short'
status = 406
# Are the passwords the same?
if password != repeated_password:
message['password']='⚠password does not match'
message['repassword']='⚠ password does not match'
status = 406
# Is the mail format correct?
if not re.fullmatch(regex, email):
message['email']='⚠ Wrong mail format'
status = 406
if status == 200:
message['common'] = '✔you have successfully registered, redirect'
message['username'] = '✔ Ok'
message['email'] = '✔ Ok'
message['password'] = '✔ Ok'
message['repassword'] = '✔ Ok'
# Saving data from the submitted form
user = User(name=username, about=about, avatar=avatar, email=email, password=password)
user.save()
return JsonResponse(message, status=status)
else:
status = 403
return JsonResponse(message, status=status)
This is how I identify form “errors” in Django.
Gather all together in registration page
Now, for everything to work, I need to create a template that would load the appropriate script and styles, use the token.
Here is the form code
{% csrf_token %}
And at the very bottom before the body tag, insert a script written in advance
{% csrf_token %}
Setup urls.py for user authentication
Need to add 2 additional paths and import corresponding functions
from .views import login, login_verify, logout
urlpatterns = [
# This function will clear the session of previously created variables
path('logout/', logout, name='logout'),
# This function will display a login form for the user
path('login/', login, name='login'),
# This function will set the appropriate session variables for the corresponding user and decide whether he can log in or not
path('login/verify-login/', login_verify, name='login_verify'),
]
Writing down ajax request for login page with email
The principle is the same as during registration. We indicate the request type, request url and data that we want to transfer. And in addition, of course, feedback for the user. So that he knows about the mistakes he made when filling out the form. All this is in a separate file login.js
function OnLogin(){
var username = $("#username").val()
var password = $("#password").val()
$.ajax({
type: "POST",
url: 'verify-login/',
data: {
'username': username,
'password': password,
},
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin',
success: function(result){
$(".hint-required").css("color","green")
$("#common-error").text(result.common)
$("#username-error").text(result.username)
$("#password-error").text(result.password)
setTimeout(function(){
window.location.href = '/'
},1000)
},
error: function(jqXHR, textStatus, errorThrown){
$(".hint-required").css("color","red")
$("#common-error").text(jqXHR.responseJSON.common)
$("#username-error").text(jqXHR.responseJSON.username)
$("#password-error").text(jqXHR.responseJSON.password)
}
})
}
$(document).ready( function(){
$("#login").on('click',OnLogin)
})
Writing down function for managing user login
Here are ready-made functions for processing and checking data entered by the user
def login_verify(request):
message = {
'common': '',
'username': 'required',
'password': 'required',
}
status = 200
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
message['common']='✖ I can not enter'
if len(username) == 0:
message['username']='⚠username fiels is empty'
status = 406
if len(password) == 0:
message['password']='⚠ password fiels is empty'
status = 406
required_user = User.objects.filter(name=username)
# User already exist
if required_user.exists():
# The entered password matches the saved one
if required_user.first().password == password:
status = 200
# Set the status of the current session as registered
request.session["is_auth"] = True
# We save the username in the current session variable
#This may be useful for displaying information intended
# Only for user
request.session["username"] = username
message['common'] = '✔ You have successfully logged in, redirect ... '
message['username'] = '✔ Ok'
message['password'] = '✔ Ok'
else:
message['password'] = '⚠ Wrong password'
status = 406
else:
message['username'] = '⚠This user does not exist'
status = 406
return JsonResponse(message, status=status)
User exit function. I'm simply clearing the current user session on my site. And I redirect to the site login page.
def logout(request):
request.session.flush()
return HttpResponseRedirect("/login")
Template for authentication on website
And of course my template for logging into the site
{% csrf_token %}
And of course, don’t forget to insert the script into the template. The login.js and jQuery library we wrote
{% csrf_token %}
In Conclusion
In this case, I demonstrated two main forms for a user authentication system. Registration form and login form. Not the most difficult thing, especially if you know what you're doing.
I want to make a reservation right away: I did not add a captcha or email verification here for one simple reason. This is authentication on my site and I didn't need it. In my activities, it is not the number of users that is important, but their quality. That is, if a person wants to contact me, he will contact me, if not, well, that’s his business.
Additional content
Github repository
The repository that I use to develop this site
Specifically in this case, you will be interested in the following files:
- Script written in jQuery for registration
- Script written in jQuery for login page
- Setting up ulrs
- Directly the page rendering function, signup login logout
- And of course the template that django uses to render the registration form
- And of course the template that django uses to render the login form
Content that I’ve used to learn
Comments
(0)
Send
It's empty now. Be the first (o゚v゚)ノ
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 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.
- Django template ⟶ This is a text document marked up with a special syntax for inserting new code.
Related questions
- 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.
- Why did you choose django over website builders ? Quite a difficult question. I guess I like to understand and delve into complex things, although it seems that it’s not worth it. It's a similar story with game development. Instead of making games using game engines, I made my own, **DI**. Well, I'm just not looking for easy ways ;)
- My App doesn't render correctly on the server? If it doesn't work, in 99% of cases it's a configuration issue. A missing property, a wrong call order, or a missing component – server-side rendering is strict about configuration. The best way to find out what's wrong is to compare your project to an already working setup. Check out the reference implementations, bit by bit.