I am using Django REST Framework alongside with rest_framework_simplejwt and trying to write my own middleware, that will update user.last_request every time user performs one.
from django.utils.timezone import now
class LastRequestMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.user.is_authenticated:
request.user.last_request = now()
request.user.save()
response = self.get_response(request)
return response```
But every time `user.is_authenticated` returns `False'
The easiest way I found to fix this problem is to authenticate user inside middleware manually. New code looks like this:
from django.utils.timezone import now
from rest_framework_simplejwt.authentication import JWTAuthentication
class LastRequestMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
user = JWTAuthentication().authenticate(request)[0]
if user:
user = user[0]
if user.is_authenticated:
user.last_request = now()
user.save(update_fields=['last_request'])
response = self.get_response(request)
return response
This is an easy-fix, so if you need user authentication functionality in many middlewares, consider using separate AuthMiddleware for SimpleJWT authentication.
I want to add a security filter so that every request to my django app will go through the filter first and then let the request go through if the token from the header is valid.
How can I accomplish that in django?
Thanks.
You can add a new middleware like this:
class SecurityMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
token = request.META.get('HTTP_AUTHORIZATION')
if token != "Some Value":
return HttpResponse('Unauthorized', status=401)
response = self.get_response(request)
return response
Then add this to the MIDDLEWARE in settings.py.
MIDDLEWARE = [
...
'path.to.SecurityMiddleware'
]
More information can be found in custom middleware documentation and request and response object documentation.
FYI, if you want to implement a standard authentication system like JWT or basic auths, consider using thrid party libraries like Simple JWT with Django Rest Framework or so on.
I want to use request.user in Django Rest Framework custom middleware.
It returns AnnonymousUser and I failed.
I created new Custom middleware which returns real user.
from django.contrib.auth.middleware import get_user
from django.utils.functional import SimpleLazyObject
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
class AuthenticationMiddlewareJWT(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
request.user = SimpleLazyObject(lambda: self.__class__.get_jwt_user(request))
return self.get_response(request)
#staticmethod
def get_jwt_user(request):
user = get_user(request)
if user.is_authenticated:
return user
jwt_authentication = JSONWebTokenAuthentication()
if jwt_authentication.get_jwt_value(request):
user, jwt = jwt_authentication.authenticate(request)
return user
Above middleware, jwt_authentication.get_jwt_value(request), this returns always None.
How can I fix it and use request.user in custom middleware?
I'm trying to use catch the Django user in the Middleware but without success. Using Python 3.6 and Django 1.11.
from threading import local
_user = local()
class CurrentUserMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
_user.value = request.user
return self.get_response(request)
def get_current_user():
return _user.value
I need to save the request.user outside the class, in the get_current_user(), but it is not working.
Can someone give me a clue why I can't have the _user.value in the get_current_user() ?
The reason I'm doing this is to import to a model
from current_user import get_current_user
Thanks,
In Django application I am working on right now, user session is marked as multiple after same user login on another device, so after page reloading first user logs out and is redirected to admin/login page.
Need to show first user warning about this on admin/login page. The only thing, that came up on my mind for now is to add GET parameter to this page url, check it in view, and show this warning. But I can't find the class/method to override, where I can check if session is expired or not and add GET parameter, say multiple_sessions=1 url.
I assume, it would look something like this:
def logout(self, request, *args, **kwargs):
if request.session['multiple']:
super(CustomLogout, self).logout(request, redirect_to='/admin/login?multiple_session=1', *args, **kwargs)
else:
super(CustomLogout, self).logout(request, *args, **kwargs)
So the question is, what exactly method is responsible for redirecting user to logout?
Any other ideas of achieving this behaviour are greatly appreciated!
Not sure if I understood correctly. Your question is, how to show a message to the user after they logged out, is that correct?
Django has the messages framework to do just that, showing messages to a user.
from django.contrib import messages
def logout(self, request, *args, **kwargs):
if request.session['multiple']:
messages.info(request, 'Something multiple sessions.')
super(CustomLogout, self).logout(request, *args, **kwargs)
Used this custom middleware class to achieve needed behavior:
class LogoutMiddleware(object):
def process_response(self, request, response):
if hasattr(request, 'user'):
if request.user.is_authenticated() and request.session.exists(request.session.session_key):
current_session = Session.objects.get(pk=request.session.session_key)
if current_session.old == True:
response_redirect = HttpResponseRedirect(reverse('logout'))
response_redirect.set_cookie('multiple-sessions', True)
return response_redirect
return response
Then, if the login view finds this cookie, it renders warning in template.