在 Hot Chocolate graphql 中审计查询的正确位置

Correct place to audit query in Hot Chocolate graphql

我在想我是否应该在 HttpRequestInterceptorDiagnosticEventListener 中审核 Hot Chocolate v11 的用户查询。后者的问题是,如果审计未能写入 disk/db,用户将“逃脱”查询。

理想情况下,如果审核失败,则不应进行任何操作。因此理论上我应该使用 HttpRequestInterceptor.

但是我如何从 IRequestExecutorIQueryRequestBuilder 得到 IRequestContext。我尝试使用谷歌搜索,但文档有限。

都不是:)

HttpRequestInterceptor 用于使用上下文数据丰富 GraphQL 请求。

另一方面,DiagnosticEventListener 用于日志记录或其他检测。

如果你想写审计日志,你应该改用请求中间件。可以像下面这样添加一个请求中间件。

services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .UseRequest(next => async context => 
    {

    })
    .UseDefaultPipeline();

这里棘手的部分是在正确的时间检查请求。您可以像下面这样定义自己的管道,而不是附加到默认管道。

services
    .AddGraphQLServer()
    .AddQueryType<Query>()
    .UseInstrumentations()
    .UseExceptions()
    .UseTimeout()
    .UseDocumentCache()
    .UseDocumentParser()
    .UseDocumentValidation()
    .UseRequest(next => async context =>
    {
        // write your audit log here and invoke next if the user is allowed to execute

        if(isNotAllowed) 
        {
            // if the user is not allowed to proceed create an error result.
            context.Result = QueryResultBuilder.CreateError(
                ErrorBuilder.New()
                    .SetMessage("Something is broken")
                    .SetCode("Some Error Code")
                    .Build())
        }
        else 
        {
            await next(context);
        }
    })
    .UseOperationCache()
    .UseOperationResolver()
    .UseOperationVariableCoercion()
    .UseOperationExecution();

该管道基本上是默认管道,但会在文档验证后立即添加您的中间件。此时,您的 GraphQL 请求已被解析和验证。这意味着我们知道这是一个可以在此时处理的有效 GraphQL 请求。这也意味着我们可以使用包含已解析 GraphQL 请求的 context.Document 属性。

为了将文档序列化为格式化字符串,请使用 context.Document.ToString(indented: true)

好处是在中间件中,我们处于异步上下文中,这意味着您可以轻松访问数据库等。与此相反,DiagnosticEvents 是同步的,并不意味着有繁重的工作量。

中间件也可以包装成 class 而不是委托。

如果您需要更多帮助,请加入我们。

点击社区支持加入松弛频道: https://github.com/ChilliCream/hotchocolate/issues/new/choose