在 django-graphql-jwt 中使用 @login_required 进行查询/突变会导致 graphql.error.located_error.GraphQLLocatedError
Posted
技术标签:
【中文标题】在 django-graphql-jwt 中使用 @login_required 进行查询/突变会导致 graphql.error.located_error.GraphQLLocatedError【英文标题】:Using @login_required for queries/mutations in django-graphql-jwt leads to graphql.error.located_error.GraphQLLocatedError 【发布时间】:2021-05-28 02:25:22 【问题描述】:我是 GraphQL 的初学者,开始使用 Django 开发一个小应用程序,并决定使用 django-graphql-jwt 进行身份验证。
我可以毫无问题地使用 getTokenAuth、VerifyToken 和 RefreshToken。但是当我尝试使用带有装饰器@login_required 的查询时,我得到的只是“GraphQLLocatedError:您无权执行此操作”响应。但是,不知何故,单元测试运行良好。
我的代码:
settings.py
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
GRAPHENE =
"SCHEMA": "myproject.graphql.api.schema",
"MIDDLWARE": [
"graphql_jwt.middleware.JSONWebTokenMiddleware",
],
GRAPHQL_JWT =
"JWT_ALLOW_ARGUMENT": True,
"JWT_VERIFY_EXPIRATION": True,
"JWT_EXPIRATION_DELTA": timedelta(minutes=5),
"JWT_REFRESH_EXPIRATION_DELTA": timedelta(days=7),
"JWT_AUTH_HEADER_NAME": "Authorization",
"JWT_AUTH_HEADER_PREFIX": "Bearer",
AUTHENTICATION_BACKENDS = [
"graphql_jwt.backends.JSONWebTokenBackend",
"django.contrib.auth.backends.ModelBackend",
]
查询.py
from graphene import String, ObjectType
from graphql_jwt.decorators import login_required
class HelloQuery(ObjectType):
hello = String(name=String(default_value="stranger"))
@login_required
def resolve_hello(self, info, name):
return f"Hello name!"
tests.py
from graphql_jwt.testcases import JSONWebTokenTestCase
from users.factories import UserFactory
class QueryTest(JSONWebTokenTestCase):
def setUp(self):
self.user = UserFactory()
self.client.authenticate(self.user)
super().setUp()
def test_00_hello(self):
"""
This test evaluates the HelloQuery
"""
query = """
query hello
hola: hello(name: "tester")
"""
result = self.client.execute(query)
self.assertIsNone(result.errors)
self.assertEqual("Hello tester!", result.data["hola"])
请求信息
POST http://localhost:8000/graphql
200
34 ms
Network
Request Headers
X-CSRFToken: 7ZZrDHmpkly1FHexdLASComfiqCo81iaHOHJuywRabRHsdIDgKbBXK3ex687G7Xt
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImpvY2hvIiwiZXhwIjoxNjE0MjczNTcxLCJvcmlnSWF0IjoxNjE0MjczMjY0fQ.C6yDzim5jliu6yIMDJ70Xl3WPP69HpYTR0VSGmy0brc
Content-Type: application/json
User-Agent: PostmanRuntime/7.26.10
Accept: */*
Cache-Control: no-cache
Postman-Token: 80a0c7fe-34c1-4972-8c3f-9342e9d047e1
Host: localhost:8000
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 63
Cookie: JWT=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImpvY2hvIiwiZXhwIjoxNjE0MjczNTcxLCJvcmlnSWF0IjoxNjE0MjczMjY0fQ.C6yDzim5jliu6yIMDJ70Xl3WPP69HpYTR0VSGmy0brc; csrftoken=7ZZrDHmpkly1FHexdLASComfiqCo81iaHOHJuywRabRHsdIDgKbBXK3ex687G7Xt
Request Body
query: "query hello
hola: hello(name: "tester")
"
variables: ""
Response Headers
Date: Thu, 25 Feb 2021 17:14:37 GMT
Server: WSGIServer/0.2 CPython/3.9.1
Content-Type: application/json
Vary: Cookie
X-Frame-Options: DENY
Content-Length: 149
X-Content-Type-Options: nosniff
Referrer-Policy: same-origin
Set-Cookie: csrftoken=7ZZrDHmpkly1FHexdLASComfiqCo81iaHOHJuywRabRHsdIDgKbBXK3ex687G7Xt; expires=Thu, 24 Feb 2022 17:14:37 GMT; Max-Age=31449600; Path=/; SameSite=Lax
Response Body
"errors":["message":"You do not have permission to perform this action","locations":["line":2,"column":5],"path":["hola"]],"data":"hola":null
【问题讨论】:
【参考方案1】:我认为您应该将您的queries.py
代码 sn-p 更改如下:
from graphene import String, ObjectType
class HelloQuery(ObjectType):
hello = String(name=String(default_value="stranger"))
def resolve_hello(self, info, name):
user = info.context.user
if user.is_authenticated:
return f"Hello name!"
return None
请注意,最新的 graphene
版本 (v0.3.0
) 有一个未解决的问题,您必须将 PyJWT==1.7.0
包添加到您的 requirements.txt
中以解决该问题 – (relevant question)
【讨论】:
以上是关于在 django-graphql-jwt 中使用 @login_required 进行查询/突变会导致 graphql.error.located_error.GraphQLLocatedError的主要内容,如果未能解决你的问题,请参考以下文章
在 django-graphql-jwt 中使用 @login_required 进行查询/突变会导致 graphql.error.located_error.GraphQLLocatedError
DJANGO-GRAPHQL-JWT:我们如何知道刷新令牌发布后的年龄?