Django middlewares with Rest Framework
Due to some design decisions in Django Rest Framework, the request.user is not available in the middleware request layer but only the views layer. Which means any extensible middlewares that you can think of getting, will not have access to the user object. Some examples of top off my head: apps like django-auditlog
, django-simple-history
, a middleware which customizes API responses based on user attributes, etc.
Below is a simple middleware which does Token Authentication allowing the request.user
object to be populated everywhere. Note: This is based on this brilliant answer.
A simple snippet below makes the request.user
object available using Token authentication.
class RestAuthMiddleware: def __init__(self, get_response): self.get_response = get_response @staticmethod def get_user(request): user = get_user(request) if user.is_authenticated: return user token_authentication = TokenAuthentication() try: user, token = token_authentication.authenticate(request) except: pass return user def __call__(self, request): request.user = SimpleLazyObject(lambda: self.__class__.get_user(request)) response = self.get_response(request) return response
This middleware can just be placed above any middleware which needs access to the request object, will run with any other middlewares that depend on request.user
object.
Custom User Response language middleware
At the same time, we had a requirement to serve API results in the user’s language, so instead of using the standard Language middleware, I implemented a simple custom middleware which uses the user’s language (and also override it using the lang=hi parameter).
Building a language middleware is easy:
class LanguageMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): language = request.user.language_code() # Override language using query parameter language = request.GET.get('lang', language) if language is not None: activate(language) response = self.get_response(request) if language is not None: deactivate() return response
Hi – thanks – great !!!
just add this at line 5
if request.user.is_anonymous:
return self.get_response(request)
Do you mean in the RestAuthMiddleware? Because that would be incorrect.
The user would always be anonymous when it comes to the middleware till we verify that the token is valid.