在 Hot Chocolate graphql 中审计查询的正确位置
Correct place to audit query in Hot Chocolate graphql
我在想我是否应该在 HttpRequestInterceptor
或 DiagnosticEventListener
中审核 Hot Chocolate v11 的用户查询。后者的问题是,如果审计未能写入 disk/db,用户将“逃脱”查询。
理想情况下,如果审核失败,则不应进行任何操作。因此理论上我应该使用 HttpRequestInterceptor
.
但是我如何从 IRequestExecutor
或 IQueryRequestBuilder
得到 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
我在想我是否应该在 HttpRequestInterceptor
或 DiagnosticEventListener
中审核 Hot Chocolate v11 的用户查询。后者的问题是,如果审计未能写入 disk/db,用户将“逃脱”查询。
理想情况下,如果审核失败,则不应进行任何操作。因此理论上我应该使用 HttpRequestInterceptor
.
但是我如何从 IRequestExecutor
或 IQueryRequestBuilder
得到 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