在生产上禁用GraphQL自省请求

时间:2019-01-06 14:33:22

标签: ruby-on-rails ruby graphql graphql-ruby

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

我该如何实现?

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

3 个答案:

答案 0 :(得分:2)

来自graphql-ruby documentation

  

您可以通过在自省命名空间中创建自定义EntryPoints类来重新实现这些字段或创建新字段:

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

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


FWIW,here is the original code您将要覆盖。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

  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