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

问题描述

我在考虑是否应该审核 HttpRequestInterceptorDiagnosticEventListener 中 Hot Chocolate v11 的用户查询。后者的问题在于,如果审计未能写入磁盘/数据库,用户将“逃脱”查询。

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

但是我如何从 IRequestContextIRequestExecutor 获取 IQueryRequestBuilder。我尝试使用谷歌搜索,但文档有限。

解决方法

都没有:)

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 是同步的,并不意味着有繁重的工作量。

中间件也可以包装成一个类而不是一个委托。

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

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...