Django — middleware authentication

In this article, we shall see how to authenticate the users in the middleware. In my Django project, I wanted to authenticate the users in the middleware instead of authenticating them in the views functions. If you are using Django Rest Framework the authentication automatically happens in the middleware. But, if we are not using the DRF or want to authenticate manually in the middleware you can make use of this article.

Photo by Jason Blackeye on Unsplash

In order to add a middleware function, we have to create a function somewhere in our project and add the name of the middleware class to the settings.py file under the MIDDLEWARE list.

I have a student app like this in my Django project.

app structure

I have added a new file called middleware.py. I will be creating a class that will check if the user is authenticated here.

The middleware

In Django middleware, there is a method called process_view(). Theprocess_view() method is called just before Django calls the view. You can name the middleware class whatever you want but the method name should be process_view() only.

The syntax of process_view() method is,

process_view(request, view_func, view_args, view_kwargs)

The arguments are

  1. request: A request is an HttpRequest object. The same object which we will obtain and process in our view function.
  2. view_func: This is the function itself and not the name. The function from the views.py file that our urls.py routes our request to is the view_func.
  3. args and view_kwargs: view_args is a list of positional arguments that will be passed to the view, and view_kwargs is a dictionary of keyword arguments that will be passed to the view.

So this is how our middleware class will look like.

from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
class ProcessRequestMiddleware(MiddlewareMixin): def process_view(self, request, view_func, *view_args, **view_kwargs):
# do something

The process_view() method should return either None or an HttpResponse object. If it returns None, Django will continue processing this request, executing any other process_view() middleware and, then, the appropriate view. If it returns an HttpResponse object, Django won’t bother calling the appropriate view; it’ll apply response middleware to that HttpResponse and return the result.

How to make it work?

We are going to make use of this HttpResponse object to return a response object, in the middleware itself with a status code of 401 if the user is not authenticated.

The status code 401 indicates that the request has not been applied because it lacks valid authentication credentials for the target resource.

Check if the user is authenticated

First, we will retrieve the user object from the request object like this.

user = request.user

The user object has an attribute called is_authenticated which will return a boolean value indicating if the user is authenticated or not.

user = request.user
if user.is_authenticated:
return HttpResponse(status=200)
else:
return HttpResponse(status=401)

Putting it all together our middleware will look like this.

The next important thing is to add our middleware to the MIDDLEWARE list in the settings.py file.

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django_user_agents.middleware.UserAgentMiddleware',
'student.middleware.ProcessRequestMiddleware'
]

I have highlighted my custom middleware. This is how you should declare your middleware to the settings.py file. Unless declared here, the middleware will not work or has any effect on the requests.

Conclusion

Hope this article is helpful. Happy coding!