You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django自定义认证后端处理Shopify请求返回401未授权问题

问题背景

我需要对来自Shopify app bridge的Shopify请求做认证,该机制会将编码后的数据添加到请求头中,再将请求发送至应用的接口端点。
通常应用使用JWT令牌对React前端技术栈发起的请求做认证,但Shopify请求需要采用不同的认证流程:先解码请求头中的数据,再对解码后的数据做合法性校验,最终返回匹配的请求用户。

我编写了如下自定义backend处理上述全部认证流程:
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:
            # Shopify Session Token 校验流程
            # ...
            if shopify_user:
                return shopify_user.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

请求首先会经过middleware,在中间件中调用authenticate()函数。该函数会收集所有可用的backend,当请求通过全部校验规则时完成请求用户认证,本场景下的校验为Shopify要求的几项请求真实性核验规则。
校验通过后,从数据库中查询到的用户会被赋值给request.user,代表认证流程执行成功,对应自定义中间件代码如下:
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

目前遇到的问题是:接口响应始终返回401 Unauthorized状态码,排查发现是响应返回阶段请求被重新初始化,导致request.user被重置为AnonymousUser,暂未定位到问题根因。


根因排查与解决方案

按优先级依次排查以下问题:

  • 中间件顺序配置错误
    Django中间件按照配置列表顺序从上到下执行process_request逻辑,返回响应时从下到上执行process_response逻辑。自定义的ShopifyMiddleware必须放在django.contrib.auth.middleware.AuthenticationMiddleware之前,否则Django自带的认证中间件会先将request.user初始化为匿名用户,后续流程触发用户惰性加载时会覆盖手动设置的用户值。
    正确配置参考:

    MIDDLEWARE = [
        # 其他前置中间件
        "your_app_path.middleware.ShopifyMiddleware",
        "django.contrib.auth.middleware.AuthenticationMiddleware",
        # 其他后置中间件
    ]
    
  • 手动赋值用户未触发Django登录绑定逻辑
    直接给request.user赋值不会触发Django的用户缓存和持久化逻辑,后续流程调用request.user时会触发惰性加载,从session或其他默认认证源重新拉取用户,覆盖之前设置的值。需要替换手动赋值逻辑,调用Django自带的login()函数完成用户绑定:

    from django.contrib.auth import authenticate, login
    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:
                    # 显式指定使用的认证后端,避免Django找不到对应backend抛出异常
                    login(request, user, backend="your_app_path.backends.ShopifySessionTokenBackend")
    
  • 自定义Backend存在基础配置错误
    贴出的代码中ShopifySessionTokenBackend继承了BaseBackend但未导入该基类,会导致Backend注册失败,authenticate()根本不会走到自定义校验逻辑,需要补上导入:

    from django.contrib.auth.backends import BaseBackend
    

    同时确认settings.py中已经将自定义Backend加入认证后端配置:

    AUTHENTICATION_BACKENDS = [
        "your_app_path.backends.ShopifySessionTokenBackend",
        "django.contrib.auth.backends.ModelBackend", # 保留默认后台登录认证能力
    ]
    
  • DRF认证组件覆盖了用户值
    如果接口使用Django REST Framework开发,DRF的认证逻辑会在Django中间件执行完成后运行,未配置对应认证类时,DRF会重置request.user为匿名用户返回401。需要新增对应DRF认证类:

    from rest_framework.authentication import BaseAuthentication
    from django.contrib.auth import authenticate
    
    class ShopifySessionAuthentication(BaseAuthentication):
        def authenticate(self, request):
            user = authenticate(request=request)
            if user:
                return (user, None)
            return None
    

    将该类加入DRF全局认证配置,或在对应视图中通过authentication_classes属性指定即可。

  • 跨域凭证配置缺失
    若前端为跨域请求,未开启凭证传递配置时,即使后端认证成功,后续请求也不会携带认证信息,Django会持续将用户识别为匿名用户。前端请求需要开启credentials: 'include'参数,后端django-cors-headers配置同步开启凭证支持,注意开启凭证时不能配置全源允许,需要指定可信域名:

    CORS_ALLOW_CREDENTIALS = True
    CORS_ALLOWED_ORIGINS = [
        "https://your-shopify-store.myshopify.com",
    ]
    

内容的提问来源于stack exchange,提问作者thepylot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.14 16:15:48