Comments (30)
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))
from django-rest-framework-jwt.
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
from django-rest-framework-jwt.
so this will authenticate twice in a request ?
from django-rest-framework-jwt.
Hi Folks. I'm having this issue too. I'm new to django-rest-framework-jwt, and somewhat new to DRF. Two questions:
- I'm confused about why the above middleware solutions are required at all. As a new user, I expected all this to be working already. How is it useful to and end users when the request.user is not extracted from the JWT token?
- I saw this mentioned: encode/django-rest-framework#2155 . I'm using DRF 3.8.2, which is more recent than the change there, but still no joy. Does this DRF change solve the problem?
Thank you!
from django-rest-framework-jwt.
Thanks @cancan101 and everyone else 👍 However my situation was a little different since we had no use for the session store or django.contrib.auth
-- we are using a lightweight version of django as a microservice for managing user authentication. However, we had 2 views that were non-api that depended on the @login_required
decorator and they would fail obviously due to the AnonymousUser
issue mentioned above. FYI we are also using django for all the other services but using builtin authorization so the service doesn't need to reach out to the users/auth service each time.
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 @login_required
decorator. Ergo, this makes adding something like django-oauth-toolkit a cinch (with a little customization to make it return JWT instead of a stored standard token).
We have actually built a very lightweight version of django skeleton
that we have used for many microservices - each using separate datastores - to much success. I'm actually very impressed with the performance.
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 request.user
to an actual User
instance vs AnonymousUser
- I know its not relative to all cases but it would be very useful. I'd be happy to write the docs and answer any questions about how we're using django for microservices very successfully.
from django-rest-framework-jwt.
should this be added to the package as an optional include?
from django-rest-framework-jwt.
Exactly what I were looking for.
I think that's impossible for now retrieving who's the user performs the request via the jwt header, beacause you need to use the "authentication_classes" attribute in the ApiView/ViewSet extended class to retrieve the user.
from django-rest-framework-jwt.
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 AuditMiddleware
.
from django-rest-framework-jwt.
Closing this for now.
from django-rest-framework-jwt.
This happens because the AuthenticationMiddleware
, which sets the user
on the request
expects to use the session store: https://github.com/django/django/blob/0f7f5bc9e7a94ab91c2b3db29ef7cf000eff593f/django/contrib/auth/__init__.py#L159.
from django-rest-framework-jwt.
@cancan101 interesting, thanks for sharing
from django-rest-framework-jwt.
I think you missed this import:
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from django-rest-framework-jwt.
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:
vvangelovski/django-audit-log#28
from django-rest-framework-jwt.
i used @cancan101 solution. Thanks
from django-rest-framework-jwt.
Django-audit-log already added a fix. So you dont need to monkey patch.
from django-rest-framework-jwt.
Thanks @klahnen - but im not using the audit_log, i need the request.user in a prprietary middleware
from django-rest-framework-jwt.
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
from django-rest-framework-jwt.
@cancan101 thank you for your clean solution, it's working great with the missing import pointed out by @klahnen
from django-rest-framework-jwt.
👍 thanks @cancan101, i needed this too
from django-rest-framework-jwt.
Thanks @cancan101
from django-rest-framework-jwt.
@AndrewJHart does it matter where in the middleware ordering this goes?
from django-rest-framework-jwt.
Hi everyone, i have this code:
from django.contrib.auth.middleware import get_user
from django.utils.functional import SimpleLazyObject
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
class AuthenticationMiddlewareJWT(MiddlewareMixin):
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
And this jwt_authentication.get_jwt_value(request) always return None.
My configurations is:
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
What can be wrong?. Thanks!
from django-rest-framework-jwt.
@mapeveri
You should create a new issue.
from django-rest-framework-jwt.
It is so cool@cancan101
from django-rest-framework-jwt.
@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:
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):
from rest_framework_simplejwt.authentication import JWTAuthentication
user = get_user(request)
if user.is_authenticated:
return user
try:
user_jwt = JWTAuthentication().authenticate(Request(request))
if user_jwt is not None:
return user_jwt[0]
except:
pass
return user # AnonymousUser
from django-rest-framework-jwt.
Following up on @rserro 's solution, I get a rest_framework.exceptions.AuthenticationFailed
error when the token is expired - at the line user, jwt = jwt_authentication.authenticate(request)
. Has anyone encountered this problem? I can catch the error and return user
(AnonymousUser), but I'd prefer to return a response that indicates the root problem - expiration. Thank you.
from django-rest-framework-jwt.
@gabn88 Thank you. Question: In your code, you use djangorestframework-simple-jwt's JWTAuthentication
. What does that get you?
from django-rest-framework-jwt.
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))
Not working.
It doesn't work and I gets still AnonymousUser.
How can I get request.user?
from django-rest-framework-jwt.
- Check your middleware order. You may need to move your auth middleware down.
- The response you referenced is from 2015. That's an unsupported version of Django. Try this one: #45 (comment)
from django-rest-framework-jwt.
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))
Thanks i just customize your idea. It helps thank you
from django-rest-framework-jwt.
Related Issues (20)
- Is there a way that we can avoid multiple token generations for a single user if he/she try to login on different browsers? HOT 2
- JSONWebTokenAuthentication object has no attribute 'media_type'
- external server
- Call an endpoint without Authorization header HOT 1
- Add support for ES256 signing algorithm
- [feature] permit to use custom header instead of `Authorization`
- registration
- how to refresh existing tokens??? HOT 6
- redis cache HOT 1
- WinError 123 after tutorial HOT 1
- How to use this library by only using Http Only Cookie? HOT 1
- Curious Whether JWT Still Works Given Libraries Requirements Mismatch? HOT 3
- Status HOT 12
- Documentation not found HOT 2
- Dead Link in readme.md HOT 1
- DeprecationWarning: The following fields will be removed in the future: `email` and `user_id`. HOT 1
- Hope to support the response format of custom authentication failure HOT 1
- Unreachable code when user is_active is False in. HOT 1
- Can we use allauth only for the things, where we can get involved with email verification, and jwt for others purposes like login/get api request/ post api requests....????
- Cookie not removed in request when response is 401
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-rest-framework-jwt.