I am trying to create a middleware to authenticate with JWT but in the view the request.user is always AnonymUser.
When I verify that the middleware changes the request.user by the User Model, it does, but upon reaching the view, for some reason the request.user is always anonymousUser
I'n using Django 1.11
# coding=utf-8
from django.utils.functional import SimpleLazyObject
from django.utils.deprecation import MiddlewareMixin
from django.contrib.auth.models import AnonymousUser, User
from django.conf import settings
from django.contrib.auth.middleware import get_user
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
import jwt
import json
class JWTAuthenticationMiddleware(MiddlewareMixin):
def process_request(self, request):
request.user = SimpleLazyObject(lambda: self.__class__.get_jwt_user(request))
@staticmethod
def get_jwt_user(request):
user_jwt = get_user(request)
if user_jwt.is_authenticated():
return user_jwt
token = request.META.get('HTTP_AUTHORIZATION', None)
user_jwt = None
if token is not None:
try:
user_jwt = jwt.decode(
token,
settings.SECRET_KEY,
algorithms=['HS256']
)
user_jwt = User.objects.get(
id=user_jwt['user_id']
)
except Exception as e:
user_jwt = AnonymousUser
return user_jwt
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'user.middlewares.JWTAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
Mauricio Collazos :
I was trying to replicate your error, but in my case, it works just well, I think the root cause of your problem is the exception handling method. jwt.decode can raise multiples types of exceptions, including DecodeError, ExpiredSignatureError , InvalidKeyError and many more, even the dict retrieved from jwt.decode could not have a 'user_id' key.\n\nThis is a fully working code\n\n# coding=utf-8\nimport jwt\nimport traceback\n\nfrom django.utils.functional import SimpleLazyObject\nfrom django.utils.deprecation import MiddlewareMixin\nfrom django.contrib.auth.models import AnonymousUser, User\nfrom django.conf import LazySettings\nfrom django.contrib.auth.middleware import get_user\n\nsettings = LazySettings()\n\n\nclass JWTAuthenticationMiddleware(MiddlewareMixin):\n def process_request(self, request):\n request.user = SimpleLazyObject(lambda: self.__class__.get_jwt_user(request))\n\n @staticmethod\n def get_jwt_user(request):\n\n user_jwt = get_user(request)\n if user_jwt.is_authenticated():\n return user_jwt\n token = request.META.get('HTTP_AUTHORIZATION', None)\n\n user_jwt = AnonymousUser()\n if token is not None:\n try:\n user_jwt = jwt.decode(\n token,\n settings.WP_JWT_TOKEN,\n )\n user_jwt = User.objects.get(\n id=user_jwt['data']['user']['id']\n )\n except Exception as e: # NoQA\n traceback.print_exc()\n return user_jwt\n\n\nJust a few more considerations, is always a good practice use LazySettings instead settings Check this thread\n\nAlso this is my middleware order\n\nMIDDLEWARE = [\n 'django.middleware.security.SecurityMiddleware',\n 'django.contrib.sessions.middleware.SessionMiddleware',\n 'corsheaders.middleware.CorsMiddleware',\n 'django.middleware.common.CommonMiddleware',\n 'django.middleware.csrf.CsrfViewMiddleware',\n 'django.contrib.auth.middleware.AuthenticationMiddleware',\n 'applications.custom_authentication.middleware.JWTAuthenticationMiddleware', # This is my middleware\n 'django.contrib.messages.middleware.MessageMiddleware',\n 'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n\n\nJust remember to put your custom middleware after django.contrib.auth.middleware.AuthenticationMiddleware middleware",
2017-11-28T21:28:28