Authentication vs Authorization: Understanding the Difference for User Creation using Django

Hadi Soufan
Tech Blog
Published in
5 min readMar 12, 2023
Photo by Micah Williams on Unsplash

Understanding the distinction between authentication and authorization is crucial for Django developers when generating user accounts for their applications. While authorization (permission) refers to deciding what actions a user can take within the program, authentication refers to confirming a user’s identity.

In this article, we will examine the distinctions between authentication and authorization in Django and how they relate to the creation of user accounts.

Authentication

Verifying a user’s identity when they attempt to connect to your application is known as authentication. The following list of built-in authentication backends is provided by Django and can be used to authenticate users:

  1. The built-in authentication mechanism of Django is used by this default authentication backend, which also enables password-based authentication through forms and APIs.
  2. Third-party authentication backends: Django also supports third-party authentication backends that let users sign in using their current social media accounts, like OAuth and social authentication.

A middleware called AuthenticationMiddleware is used in Django to carry out authentication. This middleware determines whether a valid session or token is present in the request, and if not, it sends the user to the login page. You must design a class that implements the authenticate function, which accepts a request object and, in the event of successful authentication, returns a user object, in order to build a custom authentication backend.

Authenticating users

Use authenticate() to verify a set of credentials. It takes credentials as keyword arguments, username and password for the default case, checks them against each authentication backend, and returns a User object if the credentials are valid for a backend. If the credentials aren’t valid for any backend or if a backend raises PermissionDenied, it returns None. For example:

from django.contrib.auth import authenticate
user = authenticate(username='hadysoufan', password='secret')
if user is not None:
# A backend authenticated the credentials
else:
# No backend authenticated the credentials

request is an optional HttpRequest which is passed on the authenticate() method of the authentication backends.

Note: This is a low level way to authenticate a set of credentials; for example, it’s used by the RemoteUserMiddleware. Unless you are writing your own authentication system, you probably won’t use this. Rather if you’re looking for a way to login a user, use the LoginView.

Authentication in web requests

Django uses sessions and middleware to hook the authentication system into request objects.

These provide a request.user attribute on every request which represents the current user. If the current user has not logged in, this attribute will be set to an instance of AnonymousUser, otherwise it will be an instance of User.

You can tell them apart with is_authenticated, like so:

if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...

How to log a user in?

A login() function is used to link an authenticated user to the current session if you have one.

login(request, user, backend=None)

Use login to log a user in from a view (). Both a User object and a HttpRequest object are required. Using Django’s session framework, login() saves the user’s ID.

Please take note that after a user registers in, all data that was set during the anonymous session is kept in the session.

The following example demonstrates how to use authenticate() and login() together:

from django.contrib.auth import authenticate, login

def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...

Authorization

On the other hand, authorization describes the process of deciding what actions a user can carry out within the program after they have successfully completed the authentication procedure. In Django, a collection of permissions connected to particular models and views manage authorization. The Permission model is used to specify permissions, which can be given to people individually or in groups.

Django provides several built-in permissions, including:

  • Access to view objects is limited to users with the “view” or “change” permission for that type of object.
  • Access to view the “add” form and add an object is limited to users with the “add” permission for that type of object.
  • Access to view the change list, view the “change” form and change an object is limited to users with the “change” permission for that type of object.
  • Access to delete an object is limited to users with the “delete” permission for that type of object.

Creating permissions programmatically

While custom permissions can be defined within a model’s Meta class, you can also create permissions directly. For example, you can create the can_publish permission for a BlogPost model in myapp:

from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
codename='can_publish',
name='Can Publish Posts',
content_type=content_type,
)

Simple Model for Registering Users in Django

This is a Django model for a Profile object that is associated with a User object through a one-to-one relationship. The Profile object has several fields that store additional information about the user, such as their name, email, bio, profile image, and location.

Image Reference: https://frontegg.com

The id field is a UUID field that is used as the primary key for the Profile object. The user field is a one-to-one relationship to the User model, which means that each Profile object is associated with exactly one User object. The name, email, username, bio, profileImg, and location fields are all optional fields that store additional information about the user.

The __str__ method is defined to return the username of the associated User object as a string. This can be useful for debugging and for displaying information about Profile objects in the Django admin interface or other parts of the application.

To enable users to edit their own profiles, you would need to create a Django view that allows users to retrieve and update their Profile objects. You would also need to define a custom permission class that checks whether the user making the request is the owner of the Profile object, and use this permission class in the view.

from django.db import models
from django.contrib.auth.models import User
import uuid

class Profile(models.Model):

id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.OneToOneField(
User, on_delete=models.CASCADE, null=True)
name = models.CharField(max_length=200, blank=True, null=True)
email = models.EmailField(max_length=500, blank=True, null=True)
username = models.CharField(max_length=200, blank=True, null=True)
bio = models.TextField(blank=True)
profileImg = models.ImageField(
upload_to='profileImg/', default='default.png')
location = models.CharField(max_length=255, blank=True)

def __str__(self):
return str(self.user.username)

The upload_to parameter in a FileField or ImageFieldspecifies the subdirectory within the MEDIA_ROOT directory where uploaded files will be stored, or you can use AWS S3 service and create a bucket to store the images in the cloud or you will face deployment issues.

Conclusion

In conclusion, the creation of user accounts in Django requires both authentication and authorization. While authorization dictates the actions a user is permitted to take inside the application, authentication confirms a user’s identity. You can make sure that your application is safe and easy to use by understanding these variations and how they apply to user account creation. You can design your own unique authentication and authorization backends and permissions to meet the unique requirements of your application using the examples provided in this article.

--

--

Hadi Soufan
Tech Blog

Full Stack Web Developer | Computing and Programming