是否可以使用graphql进行权威授权

时间:2017-09-15 12:47:10

标签: ruby-on-rails graphql pundit

我想做这样的事情:

authorize record, :some_action

解析graphql字段或变异(例如变异)

module Mutations::CreateLink
  CreateLink = GraphQL::Relay::Mutation.define do
    name "CreateLink"

    input_field :name, types.String
    input_field :url, types.String
    input_field :description, types.String

    return_field :link, Types::LinkType

    resolve -> (object, inputs, ctx) {
      Rails::logger.ap ctx[:current_user]
      Rails::logger.ap inputs[:name]
      ctx[:current_user]
      @link = Link.new(name: inputs[:name], url: inputs[:url], description: inputs[:description])
      authorize @link, :create?
      response = {
          link: @link
      }
    }
  end
end

运行以上操作时会显示以下错误: NoMethodError - GraphQL :: Relay :: Mutation无法定义'授权'

通常你写

include Pundit

在您的控制器中,但将其添加到GraphqlController没有任何区别。

我如何制作它以便graphql了解权威及其方法?

3 个答案:

答案 0 :(得分:2)

include Pundit不起作用的原因是当你包含一个模块时,包含被添加到类中,authorize方法无论如何都不会起作用,因为它意味着包含在控制器中并且基于假设在那。

但手动初始化策略非常容易:

class ApplicationPolicy
  attr_reader :user, :record

  def initialize(user, record)
    @user = user
    @record = record
  end
end

您可以通过在政策上调用适当的方法进行授权:

unless LinkPolicy.new(ctx[:current_user], @link).create?
  raise Pundit::NotAuthorizedError, "not allowed to create? this #{@link.inspect}"
end

答案 1 :(得分:1)

我在这篇博文Graphql ruby and authorization with pundit

中找到了一个有点灵活的解决方案

它建议您在graphqlcontroller中添加include Pundit,然后将控制器添加为上下文,如下所示:

context = {
  current_user: current_user,
  pundit: self
}

然后在解析字段和突变时,这样的方法被公开:

ctx[:pundit].authorize @link, :create?

Pundit将用户视为上下文中的current_user并抛出相应的错误。

答案 2 :(得分:0)

使用graphql-ruby的更高版本(在撰写本文时,我正在使用1.9.17),您可以在突变中定义authorized?方法,并包括以下内容...

Pundit.authorize context[:current_user], @link, :create?

有关Pundit authorize类方法的详细信息,请参见https://github.com/varvet/pundit/blob/df96d2ae6bcf28991c1501d5ff0bde4c42aa4acd/lib/pundit.rb#L60-L76

有关graphql-ruby的authorized?方法的详细信息,请参见https://graphql-ruby.org/mutations/mutation_authorization.html#can-this-user-perform-this-action