2

我正在寻找为我的 GraphQL 端点使用PyJWT. 问题是我不想保护我的登录突变。所以我正在尝试编写中间件来排除登录突变。

这很容易通过编写 GraphQL 中间件来实现,因为传递给中间件的参数使我能够检查查询的名称。

class JWTMiddleware(object):
    def resolve(self, next, root, info, **args):
        if info.field_name == 'login':
            return next(root, info, **args
        # rest of auth logic

但是因为 GraphQL 总是返回200,所以我不能使用状态码作为我的客户端上的身份验证失败检查。并且必须检查errors数组以查看消息是否Unauthorized存在。

错误响应示例:

{
    errors: [
        {
            message: 'Unauthorized: JWT invalid',
            ...,
        },
        ...
    ],
    data: null
}

这很好,但我更喜欢使用响应的状态代码作为我的检查,所以我决定用自定义装饰器包装 GraphQL 视图。

def jwt_required(fn):
    def wrapper(request):
        # no access to query name, just the GraphQLString
        # need function to parse the AST of a GraphQLString
        graphql_string = request.body.decode('utf-8')
        query_name = ast[0].name  # or something like this
        if query_name == 'login':
             return fn(request)
        # rest of auth logic
        return fn(request)
    return wrapper


def protected_graphql_view():
    return jwt_required(GraphQLView.as_view())


urlpatterns = [
    path('admin/', admin.site.urls),
    path('graphiql', GraphQLView.as_view(graphiql=True)),
    path('graphql', protected_graphql_view()),
    path('token/refresh', refresh_token_view),
]

通过这样做,我现在可以返回具有不同状态代码的响应。但同样的问题是我无法轻松检查请求是否用于登录并跳过身份验证逻辑,除非我可以正确解析 GraphQLString。

如果可能的话,我宁愿不定制一些东西。我会假设 GraphQL 或 Graphene 会提供类似的东西。

如果我需要提供更多信息,请告诉我。感谢您的任何帮助!

4

0 回答 0