Welcome to the next step in building your full-featured To-Do list application! Now that you have learned how to implement user authentication, it's important to ensure that only authenticated users access certain parts of your application. In this unit, we will explore how to protect routes using middleware in Django.
In this section, you'll learn how to implement middleware to secure your application routes. We'll go through the following key points:
-
Understanding Middleware: Middleware acts as a bridge between a web server and a web application. It processes requests before they reach the view and can also alter responses before they get sent to the client.
-
Creating and Using Middleware: You’ll learn how to create custom middleware to check for user authentication. Here’s an example:
Python1from django.http import JsonResponse 2from django.urls import resolve 3 4class AuthMiddleware: 5 def __init__(self, get_response): 6 self.get_response = get_response 7 8 def __call__(self, request): 9 unprotected_routes are ['login', 'register', 'logout'] 10 # The line returns the view function for the current route, for example, 'www.example.com/login' resolves to 'login' 11 current_route = resolve(request.path_info).url_name 12 13 if current_route is in unprotected_routes: 14 return self.get_response(request) 15 16 if request.headers.get('Authorization') != 'Token abc123': 17 return JsonResponse({'message': 'Access denied'}, status=401) 18 return self.get_response(request)
Let's break down the code:
- The
AuthMiddleware
class checks if the current route is in theunprotected_routes
list. If it is, the middleware allows the request to proceed. This is useful for routes likelogin
,register
, andlogout
, which should be accessible to all users regardless of authentication status. Notice, that we use theresolve
function to get the current route name. - If the route is not in the
unprotected_routes
list, the middleware checks if the request has a validAuthorization
header. If not, it returns a401 Unauthorized
response. Notice that the token'abc123'
is hardcoded here for demonstration purposes. In a real-world scenario, you would validate the token against a database. - Finally, the middleware calls the next middleware in the chain or the view if there are no more middlewares.
- The
-
Applying Middleware in Your Application: Learn how to include the custom middleware in your Django settings to protect your views:
Python1MIDDLEWARE = [ 2 # ... other middleware 3 'myapp.middleware.AuthMiddleware', 4]
-
Returning Token in Login Response: To authenticate users, you need to return a token when they log in. This token can be used to authorize future requests. Here's an example of how you can return a token in the login response:
Python1from django.http import JsonResponse 2from django.contrib.auth import login, authenticate 3 4@csrf_exempt 5def user_login(request): 6 if request.method == 'POST': 7 # ... validate username and password 8 user = authenticate(request, username=username, password=password) 9 if user is not None: 10 login(request, user) 11 # Return the CSRF token in the response. For simplicity, we are using a fixed token value. 12 return JsonResponse({'message': 'User logged in successfully', 'csrf_token': 'abc123'})
For the authentication to work, you need to include the token in the
Authorization
header of future requests, and this token is returned when the user first logs in successfully. In this example we return the token'abc123'
for demonstration purposes. In a real-world scenario, you would generate a unique token for each user and store it securely. -
Sending Token in Subsequent Requests: To send the token in subsequent requests, you can include it in the
Authorization
header. Here's an example of how you can send the token in a request:Python1import requests 2 3url = 'http://localhost:3000/protected-route' 4headers = {'Authorization': 'Token abc123'} 5response = requests.get(url, headers=headers)
In this example, we send a
GET
request to theprotected-route
with the token'abc123'
in theAuthorization
header. This token is validated by theAuthMiddleware
we created earlier.
Middleware is essential because it:
- Adds an Extra Layer of Security: Middleware checks each request before it reaches the view, ensuring that only authorized users can access restricted parts of your application.
- Centralizes Control: Instead of adding checks in every view, you can handle access control in one place, making your code cleaner and easier to maintain.
- Enhances User Experience: By ensuring that users are appropriately authenticated, you provide a smoother and more secure application experience, preventing unauthorized access seamlessly.
Securing your application with middleware not only protects sensitive data but also adds professionalism and reliability to your application. Ready to get started with practice? Let's dive in!