在生产环境中禁用 GraphQL 自省请求

Disabling GraphQL introspection requests on production

出于公司政策原因,我必须禁用 graphql-ruby gem 的内省功能(使 __schema 请求失败/return 404)。

如何实现?

该应用程序基于 Ruby Rails 版本 5.2.2,graphql-ruby gem 版本为 1.8.12。

来自graphql-ruby documentation

You can re-implement these fields or create new ones by creating a custom EntryPoints class in your introspection namespace:

module Introspection
  class EntryPoints < GraphQL::Introspection::EntryPoints
    # ...
  end
end

就是说,只需引入 def __schema 方法重定向到 404 或显式响应 404


FWIW,here is the original code 你要覆盖。

graphql-ruby (>= 1.9.7) 支持 disable_introspection_entry_points .

参见 https://github.com/rmosolgo/graphql-ruby/pull/2327

如果有人正在寻找动态选项,一种方法可能是使用自定义分析器。

  1. 在调用您的架构时传递上下文变量,例如 authorize_introspection:
class GraphqlController < ApplicationController

  def execute
    context = context.merge(authorize_introspection: admin?)

    result = MySchema.execute(query, 
      variables: variables, 
      context: context, 
      operation_name: operation_name, 
      root_value: root_value
    )
    render json: result.to_json
  end

 (...)
  1. 那就用这里吧
class QueryAnalyzer < GraphQL::Analysis::AST::Analyzer

  def on_leave_field(_node, _parent, visitor)
    introspection_field_names = %w[__schema __type]
    field_def = visitor.field_definition

    if field_def.introspection? && introspection_field_names.include?(field_def.graphql_name)
      @introspection_present = true
    end

    super
  end

  def result
    return if introspection?

    GraphQL::AnalysisError.new('Not authorized to query schema internals')
  end

  private

  def introspection?
    @introspection_present && introspection_authorized?
  end

  def introspection_authorized?
    ENV['DISABLE_INTROSPECTION_ENTRY_POINTS'] != 'true' && query.context[:authorize_introspection]
  end
end
  1. 在架构上进行声明
  class MySchema < GraphQL::Schema

    use GraphQL::Analysis::AST
    query_analyzer QueryAnalyzer

    (...)
  end

来源:https://github.com/rmosolgo/graphql-ruby/issues/1240#issuecomment-393936456