Comparing Permission Handling in Django and Express.js for Web Applications

Hikmah Yousuph
Nur: The She Code Africa Blog
4 min readSep 14, 2023

A while back, I had a task where I was required to create an API for a ride-sharing application. I initially built it using Node.js, Express.js, MongoDB, and TypeScript but later decided to create the same backend on another branch using Django. During this process, I encountered a crucial aspect: managing permissions. In this article, I will compare how Django and Express.js handle permissions differently.

Introduction

Permission is essential for the building of the backend and APIs of an application, ensuring security and integrity. Permissions are checked before the code they manifest in is authorized to run.

In Django, permissions are created through the use of the permission class while in Express.js, it is done mostly through middleware or simple functions.

Permissions in Django

Django, the framework for perfectionists, has a lot of built-in classes assigned to views that take the load off developers, making web development easier and faster. Permissions in Django Rest Framework come in two ways: built-in and custom.

Built-in Permissions:

  • IsAuthenticated: Only authenticated users (logged-in users) have access.
  • IsAdminUser: Only admin or superusers are allowed access.
  • IsAuthenticatedOrReadOnly: Grants read-only access to unauthenticated users, while authenticated users can modify data.

Here’s an example of how IsAuthenticated is used:

from rest_framework import permissions, generics
class GetAllRidesAPI (generics.ListAPIView):
queryset = DriverRide.objects.all()
serializer_class = DriverRideSerializer
permission_classes = [permissions.IsAuthenticated,]

In the code above, users can get all the rides available as long as they are authenticated. In cases where they are not, an error message will instead be returned, depicting what the user should do.

Custom Permissions:

In cases where the built-in permissions don’t meet your specific requirements, Django allows you to create custom permissions. custom permission gives the flexibility to create permissions the way you want.

To create a custom permission in Django Rest Framework, you need to create a permissions.py file:

from rest_framework import permissions
from vehicle.models import Vehicle
class HasVehicle(permissions.BasePermission):
"""
Check if the driver has a vehicle
"""
def has_permission(self, request, view):
try:
vehicle = Vehicle.objects.get(driver=request.user)
return True
except Vehicle.DoesNotExist:
self.message = "Driver need a vehicle before creating a ride."
return False

The HasVehicle permission class above checks if the user (the driver) has a vehicle in the database before allowing them to create a ride. This custom permission can be used in conjunction with built-in permissions.

This can be seen in the view for creating a new ride:

from rest_framework import generics, permissions
from ..models import DriverRide
from .serializers import DriverRideSerializer
from .permissions import HasVehicle
class CreateRideAPI (generics.CreateAPIView):
queryset = DriverRide.objects.all()
serializer_class = DriverRideSerializer
permission_classes = [permissions.IsAuthenticated, HasVehicle,]

Permissions in Express.js

Unlike Django’s ready-made solutions, Express.js provides flexibility and requires developers to implement permissions using middlewares.

Middleware

Middleware functions in Express.js have access to the request and response objects and act as middlemen between incoming HTTP requests and outgoing responses.

For instance, let’s create a middleware to check if a driver has a vehicle before creating a ride:

const isDriver = (req, res, next) => {
const driverVehicle = await Vehicle.findOne({ driver: req.user?.id });
  if (!driverVehicle) {
return res
.status(404)
.json({ message: "Driver need a vehicle before creating a ride" });
}
next();
};

The middleware is placed in the route like this:

import { createRide } from "../controllers/driverRideController";
import { verifyToken } from "../middlewares/authMiddleware";
...
app.post("/create-ride", isDriver, createRide);

Express.js allows you to use multiple middlewares for a route, either by listing them directly in the route definition or by nesting one middleware within another.

Pros and Cons

Let’s briefly explore the advantages and disadvantages of each framework:

Django:

Pros:

  • Django’s built-in functionalities reduce the workload for developers.
  • It has a great security system already set up.
  • Enables fast and scalable applications.
  • The documentation is excellently detailed and easy to understand.
  • It has great community support.

Cons:

  • Can be seen as rigid due to all the built-in functionalities.
  • It is more convenient for large and complex applications than small-scale projects.
  • It is very vast and can be cumbersome for new developers.

Express.js:

Pros:

  • Easy to learn and use.
  • Provides flexibility and control over applications.
  • Lightweight and fast.
  • Great community support.
  • Allows easy integration of libraries.

Cons:

  • Lack of built-in features
  • May require more structure for larger projects.
  • Primarily suited for small to medium-sized applications.

Conclusion

Django and Express.js are both powerful frameworks for creating APIs. Choosing between them depends on your project’s needs and your development preferences.

Managing permissions effectively is crucial in web development in order to enhance security, protect sensitive data, and provide a seamless user experience. Whether you prefer Django’s built-in approach or Express.js’s flexibility, both frameworks offer robust solutions for handling permissions in your web applications.

--

--

Hikmah Yousuph
Nur: The She Code Africa Blog

Software developer skilled in creating articles all things tech. Passionate about problem-solving, tech writing, fantasy novels, and keeping up with tech news.