使用Django GraphQL Auth携带有效令牌查询me返回Anonymous匿名用户
按排查优先级排序,你当前的配置存在以下会导致info.context.user始终为Anonymous的问题:
1. 缺失JWT认证后端
你在AUTHENTICATION_BACKENDS中主动注释了graphql_jwt.backends.JSONWebTokenBackend,但graphql_auth的身份校验链路完全依赖这个后端完成令牌解析、对应用户匹配。缺少该后端时,哪怕GraphQL流程拿到了令牌,也无法完成身份绑定,只能返回匿名用户。
修改为如下配置:
AUTHENTICATION_BACKENDS = [ 'graphql_jwt.backends.JSONWebTokenBackend', 'graphql_auth.backends.GraphQLAuthBackend', 'django.contrib.auth.backends.ModelBackend', ]
2. GraphQL中间件顺序错误
graphql_jwt.middleware.JSONWebTokenMiddleware的核心作用是从请求头解析令牌、匹配用户,将用户身份绑定到GraphQL的请求上下文上。必须保证该中间件在GRAPHENE.MIDDLEWARE列表的最前置位置,否则其他中间件会在身份绑定前就读取上下文,拿到匿名身份。
你当前的顺序虽然是正确的,但需要避免随意调换顺序:
GRAPHENE = { 'SCHEMA_INDENT': 4, 'SCHEMA': 'byt.schema.schema', 'MIDDLEWARE': [ 'graphql_jwt.middleware.JSONWebTokenMiddleware', # 必须放在第一位 'graphene_django_extras.ExtraGraphQLDirectiveMiddleware' ] }
3. 请求头格式不符合解析规则
测试场景下容易遗漏令牌的固定格式前缀,导致JWT中间件完全识别不到请求携带的令牌:
正确的
Authorization请求头格式必须满足:Authorization: Bearer <从tokenAuth接口返回的JWT值>
要求必须保留Bearer前缀,且前缀和令牌值之间有空格,不能替换成Token、JWT等其他自定义表述,也不能省略前缀直接传令牌值。
4. 全局认证中间件顺序错误
Django全局中间件是按照列表倒序处理请求的,必须保证AuthenticationMiddleware在SessionMiddleware、CsrfViewMiddleware之后,否则认证逻辑会因为缺少依赖的会话、CSRF数据,直接返回匿名身份。
核心中间件顺序参考:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', # 跨域、通用处理类中间件放在认证中间件之前 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ]
5. 跨域请求头被拦截
如果是通过前端跨域调用接口,需要确认跨域配置(如django-cors-headers)没有拦截Authorization请求头。需在配置中确认允许传递该请求头:
# settings.py CORS_ALLOW_HEADERS = [ "accept", "accept-encoding", "authorization", # 必须包含该头配置 "content-type", "dnt", "origin", "user-agent", "x-csrftoken", "x-requested-with", ]
内容的提问来源于stack exchange,提问作者Roger Godofredo Rivero Morales

