-
Notifications
You must be signed in to change notification settings - Fork 651
request.user shows AnonymousUser in middleware #45
Comments
Exactly what I were looking for. |
This should be the same behavior with any Authentication class for DRF, since it doesn't happen at a Middleware layer, but at the view layer. An idea would be to perhaps create a custom DRF authentication class or even a view mixin to do whatever you're already doing in your |
Closing this for now. |
This happens because the |
This is how I fixed it. I created a new middleware: from rest_framework.request import Request
from django.utils.functional import SimpleLazyObject
from django.contrib.auth.middleware import get_user
def get_user_jwt(request):
user = get_user(request)
if user.is_authenticated():
return user
try:
user_jwt = JSONWebTokenAuthentication().authenticate(Request(request))
if user_jwt is not None:
return user_jwt[0]
except:
pass
return user
class AuthenticationMiddlewareJWT(object):
def process_request(self, request):
assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."
request.user = SimpleLazyObject(lambda: get_user_jwt(request)) |
@cancan101 interesting, thanks for sharing |
I think you missed this import: from rest_framework_jwt.authentication import JSONWebTokenAuthentication |
Hi, I know this post is old, I had same problem using django-audit-log and I applied @cancan101 patch to django-audit-log If you are interested here is the issue I reported: |
i used @cancan101 solution. Thanks |
Django-audit-log already added a fix. So you dont need to monkey patch. |
Thanks @klahnen - but im not using the audit_log, i need the request.user in a prprietary middleware |
landed here.. still can't get it working.. I noticed that when making a raw $.ajax POST request from my ember app that requires the user being authenticated, despite my jwt token being passed in the AuthorizationHeader, on the backend request.user == AnonymousUser.. I can't figure out how to populate it or why! ugh |
@cancan101 thank you for your clean solution, it's working great with the missing import pointed out by @klahnen |
👍 thanks @cancan101, i needed this too |
Thanks @cancan101 |
Thanks @cancan101 and everyone else 👍 However my situation was a little different since we had no use for the session store or Ergo, I borrowed some of @cancan101 's code and made some tweaks. from django.utils.functional import SimpleLazyObject
from django.contrib.auth.models import AnonymousUser
from rest_framework.request import Request
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
def get_user_jwt(request):
"""
Replacement for django session auth get_user & auth.get_user
JSON Web Token authentication. Inspects the token for the user_id,
attempts to get that user from the DB & assigns the user on the
request object. Otherwise it defaults to AnonymousUser.
This will work with existing decorators like LoginRequired ;)
Returns: instance of user object or AnonymousUser object
"""
user = None
try:
user_jwt = JSONWebTokenAuthentication().authenticate(Request(request))
if user_jwt is not None:
# store the first part from the tuple (user, obj)
user = user_jwt[0]
except:
pass
return user or AnonymousUser()
class JWTAuthenticationMiddleware(object):
""" Middleware for authenticating JSON Web Tokens in Authorize Header """
def process_request(self, request):
request.user = SimpleLazyObject(lambda : get_user_jwt(request)) This forces all requests to have a valid JWT before they can access any of the DRF api resources with the added benefit of still functioning properly with the We have actually built a very lightweight version of django If anyone has any questions, suggestions, or improvements I'd love to hear them. Thanks. P.S. @jpadilla Is there a chance we can get something like this added into the core package as an option for those users who depend on |
should this be added to the package as an optional include? |
@AndrewJHart does it matter where in the middleware ordering this goes? |
Django 1.10 style without suppressing exceptions. # -*- coding: utf-8 -*-
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 |
so this will authenticate twice in a request ? |
Hi everyone, i have this code:
And this jwt_authentication.get_jwt_value(request) always return None. My configurations is:
What can be wrong?. Thanks! |
@mapeveri |
It is so cool@cancan101 |
Hi Folks. I'm having this issue too. I'm new to django-rest-framework-jwt, and somewhat new to DRF. Two questions:
Thank you! |
@matthewcornell It doesn't. Which is shit, because with the authentication snippet of @cancan101 above you'll still need two database calls, because the user is authenticated twice instead of once. But I also just did it like this, because the authentication is fast and it felt like a premature optimization. But still, it does not feel very elegant for something as simple as authentication. Also please note the root cause of this issue is DRF, and not Django itself. By the way, the following is the same snippet. But then for djangorestframework-simple-jwt:
|
Following up on @rserro 's solution, I get a |
@gabn88 Thank you. Question: In your code, you use djangorestframework-simple-jwt's |
Not working. |
|
Thanks i just customize your idea. It helps thank you |
I'm not sure if this is an issue or just because of the implementation, but I was using middleware to log user_id against records being edited, and I couldn't get request.user at the middleware level (and so of course request.user.is_authorized() returned False).
The middleware was the last one on the list, and authorization was working (I would get a 403 requesting assets without my token header). I tried putting
'rest_framework_jwt.authentication.JSONWebTokenAuthentication'
at the top ofDEFAULT_AUTHENTICATION_CLASSES
, and also making it the only item in the tuple; neither worked.I've managed to work around my issue by accessing the header and using the tools directly in the app to retrieve the user; essentially I copied chunks of your code into my middleware, but I thought you should know :)
If you're interested, here's the middleware:
The text was updated successfully, but these errors were encountered: