12

我正在尝试在 ruby​​ 中创建一个宁静的 json api - 所以我在Rack 内使用葡萄( https://github.com/intridea/grape )。我没有在这个项目中使用 Rails,所以康康舞、魔法等等……似乎不是最好的选择。另外,我讨厌在葡萄的声明性 DSL 中混入一堆命令式逻辑。

虽然葡萄内置了身份验证支持,但我没有看到任何关于授权的信息。看起来这将是一个足够常见的用例,这条路以前会走过,但是在谷歌和葡萄代码库本身进行了一些相当彻底的挖掘之后,我什么也没发现。

有没有人为他们的葡萄项目实施过这样的事情?你用了什么?

4

3 回答 3

8

这可能有点太晚了,但无论如何。我建议您使用Pundit进行授权,这非常简单。要在Grape API 端点中使用它,您需要包含 Pundit 助手:

class API < Grape::API
  format :json

  helpers Pundit
  helpers do
    def current_user
      resource_owner
    end
  end

  mount FoosAPI
end

现在在您的 API 端点中,您应该能够authorize foo, action?像在 Rails 控制器中一样使用:

class FoosAPI < Grape::API
  get ':id' do
    foo = Foo.find(params[:id])
    authorize foo, :show?
    present foo, with: FooEntity
  end
end

希望能帮助到你!

于 2015-06-26T03:56:57.967 回答
1

我想我可以对此发表简短的评论,但是该字段太短了,如果不是正确答案,对不起,但是:

您提到了巫术-我认为这是身份验证系统,与授权无关。(我不知道魔法 gem 的实现——只是从文档中重复声明并假设描述枚举了它替换的此类系统并且它是有效的定义)。我想这只是错误。

你应该问自己的基本问题是......

您开发了多少基于角色的系统?我认为如果这只是公共/私人/管理员角色的问题,您可能应该考虑将其移至不同的 API。

在某些情况下这可能很麻烦,但对于不复杂的非附加角色值得一试。葡萄中的简单挂载将解决OOTB问题。

真正的问题是,如果您考虑一些可扩展/动态的角色系统,或者您只想干活。这可能很痛苦;-)。我认为 Rayan 的 Bytes cancan gem 实现应该可以帮助您了解如何在更高的抽象级别上解决此类问题。对于特定的(没有更高的抽象 - 例如动态角色)实现,只使用来自葡萄的当前给定的助手并将他们的职责委托给模型(基本用法)应该没问题。

helpers do
  def current_user
    @current_user ||= User.authorize!(env)
  end

  def authenticate!
    error!('401 Unauthorized', 401) unless current_user
  end
end

所以所有的故事都是关于如何实现 User.authorize!(env) 我相信这应该在你的模型中完成,并且完全取决于你的需要。

于 2013-02-21T19:31:47.807 回答
1

不知道我的回答对你来说是否及时。我最近在 Rails4 项目中遇到了Grape授权问题。在尝试之后,我找到了一种方法。在我的项目中,我使用权威人士进行授权,它要求我创建一个策略文件夹,并为每个模型创建授权规则,每个规则都是一个 Ruby 类,类似这样(来自权威人士 Github 页面)

class PostPolicy < ApplicationPolicy
  def update?
    user.admin? or not record.published?
  end
end

然后在 Grape API 中,我只使用这个类进行授权,代码如下:

desc "hide a post"
post :hide do
  authenticate!
  error!( "user unauthorized for this" ) unless PostPolicy.new(current_user, @post).hide_post?
  @post.update hidden: true
  { hidden: @post.hidden }
end

authenticate!助手current_user是自定义助手。通过这种方式,我可以重用开发网站部件时创建的授权规则。

这对我有用。希望权威的方式可以解决你的葡萄授权问题

于 2014-11-17T16:55:22.083 回答