Custom backend authentication returns 401 unauthorized in Django

Viewed 149

I want to authenticate Shopify requests that come from the Shopify app bridge. Simply, it adds encoded data into headers and sends requests to my app's endpoints.

Normally, my app uses JWT tokens to authenticate requests from the front-end stack (React). However, the Shopify requests require a different kind of authentication process where I have to decode the data from the header, then validate the decoded data and finally return the proper request user.

As a solution, I wrote a custom backend that handles all processes above:

backends.py

from django.contrib.auth.models import User

from shopify import session_token


class ShopifySessionTokenBackend(BaseBackend):

    def authenticate(self, request, username=None, password=None, **kwargs):
        shopify_session_token = request.headers.get("Authorization")
        try:
            # validation process for Shopify Session Token
            # ...
            if shopify_user:
                return shopify_user.user # returning proper user

        except Exception as exc:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

First, the request goes through middleware where the authenticate() function is called. Next, the authenticate() function collects all available backends to authenticate the request user if it passes all validations. In this case, validations are just a few checkings required by Shopify to verify the request authenticity.

After validations passed, retrieved user from DB sets to request.user which means authentication process was successful:

middleware.py

from django.contrib.auth import authenticate
from django.utils.deprecation import MiddlewareMixin


class ShopifyMiddleware(MiddlewareMixin):   

    def process_request(self, request):
        if not hasattr(request, "user") or request.user.is_anonymous:
            user = authenticate(request=request)
            if user:
                request.user = request._cached_user = user

The question is - response always returns with status 401 Unauthorized which is caused by reinitialization of request while sending a response. So, request.user changed back to AnonymousUser.

At this point, I don't have any clue about the reasons. Any help is appreciated.

0 Answers
Related