Identity, SaaS

Django Authentication: The Basics With a Quick Tutorial

Django, maintained by the Django Software Foundation, is an open-source and Python-based web framework. It essentially enables rapid development of applications and online services. What is important to know about Django authentication? Let’s learn more.

What Is Django Authentication?

Django is a free, open-source Python web framework that supports fast development and clean, functional design. It provides a ready-made infrastructure for Python web applications, allowing developers to focus on building application logic. 

Django provides a robust user authentication system, with support for user accounts, user groups, permissions, and cookie-based user session processing.

Although it is called “Django authentication”, the Django authentication system has a broader scope and handles both authentication (ensuring users are who they say they are) and authorization (determining what a user can do in the system, once they are authenticated). 

Django’s authentication system is very generic, by design, and does not provide many specific features commonly found in web authentication systems. You can add many of these specific features using third-party packages.

Using the Django Authentication System

Django authentication combines authentication and authorization functions in one system. This system’s core is user objects, which usually represent individuals interacting with your website. The authentication system uses these objects to enable functions such as access restriction, user profile registration, and content creator identification. 

All users in Django authentication are of the same class, although different users can have added attributes to grant them administrator status. Default users usually have a username, password, email, and first and last name.

Related: Authentication vs Authorization

Creating Users in Django 

You can create users via Django Admin or directly in Django by including the create_user helper function:

>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user(‘Name’, ‘name@email.com’, ‘userpassword’)
>>> user.last_name = ‘Surname’
>>> user.save()

Authenticating Users

Using the authenticate function to process each credential as a keyword argument, you can verify users’ credentials. It checks the credentials against the authentication backend and returns User objects if they are valid. If they are not valid for a backend or they have no permissions, Django will return “none.”

Setting Up Permissions in Django

Django’s built-in authentication system includes permissions, users, and groups. Django automatically creates four default permissions when you create a model—add, delete, change, and view. These permissions allow users to add, delete, modify, or view instances of the model respectively. 

Permissions have names following the naming convention <app>.<action>_<modelname>.

These elements specify the application’s name, the permitted action, and the model’s name (in lowercase letters).

You can grant model permissions to groups or individual users. You can verify whether a specific user has a permission using the following:

>>> from django.contrib.auth.models import User
>>> u = User.objects.create_user(username=’name’)
>>> u.has_perm(‘auth.change_user’)
False

A Django model cannot enforce permissions by itself—only Django Admin enforces permissions by default. Models are typically unaware of which user performs a given action, so you need to enforce permissions at the specific view layer. For example, you can use the following to prevent users without delete permissions from deleting user data in the User model:

from django.core.exceptions import PermissionDenied
def users_list_delet(request):
    if not request.user.has_perm(‘auth.delete_user’):
raise PermissionDenied()

If an authenticated user makes a request, there will be a User instance—otherwise, it will be an AnonymousUser instance. The has_perm always returns “false” when used on an AnonymousUser. A user without the delete_user permission will trigger a PermissionDenied exception and receive a status 403 response. 

You can enforce permissions in a template by accessing the existing user permissions through the “perms” template variable.

Authenticating in Web Requests

The Django authentication system attaches to request objects using sessions and middleware, which provide “request.user” attributes for all requests representing a given user. If the user is not logged in, the attribute will have an AnonymousUser instance. You can differentiate authenticated and anonymous users using the “is_authenticated” element:

if request.user.is_authenticated:
# Enable authenticated user’s permitted action.
    …
else:

# Enable anonymous user’s permitted action.

    …

You can attach authenticated users to the session using the login function:

login(request, user, backend=None)

You can use the login function alongside the authenticate function:

from django.contrib.auth import authenticate, login

Related: Authentication Security

Managing Users in Django Admin

The admin lets you view and easily manage permissions, users, and groups. You can create or delete a user like a Django model, and you can create a group and assign it permissions. Django Admin also stores and displays a user edit log.

The main index page should have a “Users” link in the “Auth” section. Unlike other admin pages, “Add user” requires choosing a username and password before you can edit other fields. You must give “add user” and “change user” permissions to any user account that will be creating users via Django Admin. This requirement is a security measure to prevent creating “superusers” with simple add permissions. 

Users should only have the minimum ability to manage their permissions—any user who can edit user permissions is effectively a superuser and can escalate privileges. The admin site doesn’t store or display user passwords (only their storage details). 

Quick Tutorial: Implementing User Registration, Login and Logout in Django

Let’s see how to create a simple process for user registration, login and logout in Django.

User Registration

The following code will set up a simple user registration process in Django. Create a view similar to the following.

This code imports the Django authentication system into the view and checks if the user is already authenticated. If so, it grants access to the root of the application.

from django.shortcuts import render, redirect

from django.contrib.auth import authenticate, login

from django.contrib.auth.forms import UserCreationForm

def signup(request):

    if request.user.is_authenticated:

        return redirect(‘/’)

Next, the code checks if the user is using the POST HTTP method. If so, it means they already filled out the form and we need to create a new user account. In this case, the code processes the username and password provided in the form. Otherwise, the registration form is shown.

    if request.method == ‘POST’:

        form = UserCreationForm(request.POST)

        if form.is_valid():

            form.save()

            username = form.cleaned_data.get(‘user’)

            password = form.cleaned_data.get(‘pass’)

            user = authenticate(username=user, password=pass)

            login(request, user)

            return redirect(‘/’)

        else:

            return render(request, ‘signup.html’, {‘form’: form})

Finally, if the user is not authenticated and the browser is not submitting a form, the registration form is shown:

    else:

        form = UserCreationForm()

        return render(request, ‘signup.html’, {‘form’: form})

User Login

Here is an example of code that can handle user login. As above, we first import the Django authentication system and check if the user is authenticated. If so, we redirect the user to a default page in the application.

from django.shortcuts import render, redirect

from django.contrib.auth import authenticate, login

from django.contrib.auth.forms import AuthenticationForm

def signin(request):

    if request.user.is_authenticated:

        return render(request, ‘default.html’)

Next, we check if the browser is submitting a POST request. If so, the code retrieves the username and password variables from the form, and authenticates the user using the authenticate() function.

    if request.method == ‘POST’:
  username = request.POST[‘user’]
   password = request.POST[‘pass’]
user = authenticate(request, username=username, password=passwo
rd)

If the username and password correspond to an account, we log the user in. If not, the login page is shown with their data filled in:

        if user is not None:

            login(request, user)

            return redirect(‘/’)

        else:

            form = AuthenticationForm(request.POST)

            return render(request, ‘signin.html’, {‘form’: form})

If we see the user is accessing the page for the first time, a blank login form is displayed:

    else:

        form = AuthenticationForm()

        return render(request, ‘signin.html’, {‘form’: form})

User Logout

The following code enables users to log out. When a user logs in, they start a session. In Django, sessions do not timeout by default. The logout() function explicitly terminates the user session.

from django.shortcuts import render, redirect
from django.contrib.auth import logout
def signout(request):
   logout(request)
  return redirect(‘/’)

To check if a user has an active session on their device, use the request.user.is_authenticated variable—it will be True if a session is active. Another way to determine whether the user has an active session is to add the decorator @login_required above a function.

Django Authentication with Frontegg

Frontegg’s user management platform handles authentication and authorization using modern industry standards. All session and JWT tokens generated by the platform can be validated by multiple frameworks, including Django. Frontegg embraces OS standards and packages like Python Django. Multiple libraries can handle JWT verification and validation.