Skip to content
This repository was archived by the owner on May 26, 2020. It is now read-only.
This repository was archived by the owner on May 26, 2020. It is now read-only.

request.user shows AnonymousUser in middleware #45

@marcelkornblum

Description

@marcelkornblum

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 of DEFAULT_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:

from django.db.models import signals
from django.utils.functional import curry
from django.utils import timezone
from threading import local

import jwt
from rest_framework.authentication import get_authorization_header
from rest_framework_jwt.settings import api_settings
from django.conf import settings
try:
    from django.contrib.auth import get_user_model
except ImportError:  # Django < 1.5
    from django.contrib.auth.models import User
else:
    User = get_user_model()

_user = local()

class AuditMiddleware(object):
    def process_request(self, request):
        if not request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
            if hasattr(request, 'user') and request.user.is_authenticated():
                user = request.user
            else:
                user = self.get_user_from_auth_header(request)
                if user is not None:
                    request.user = user

            _user.value = user

            mark_whodid = curry(self.mark_whodid, _user.value)
            signals.pre_save.connect(mark_whodid,  dispatch_uid = (self.__class__, request,), weak = False)

    def process_response(self, request, response):
        signals.pre_save.disconnect(dispatch_uid =  (self.__class__, request,))
        return response

    def mark_whodid(self, user, sender, instance, **kwargs):
        # user logging here

    def get_user_from_auth_header(self, request):
        try:
            auth_keyword, token = get_authorization_header(request).split()
            jwt_header, claims, signature = token.split('.')

            try:
                payload = api_settings.JWT_DECODE_HANDLER(token)
                try:
                    user_id = api_settings.JWT_PAYLOAD_GET_USER_ID_HANDLER(payload)

                    if user_id:
                        user = User.objects.get(pk=user_id, is_active=True)
                        return user
                    else:
                        msg = 'Invalid payload'
                        return None
                except User.DoesNotExist:
                    msg = 'Invalid signature'
                    return None

            except jwt.ExpiredSignature:
                msg = 'Signature has expired.'
                return None
            except jwt.DecodeError:
                msg = 'Error decoding signature.'
                return None
        except ValueError:
            return None

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions