如何(Oauth-)基于角色的Rails访问控制?

时间:2012-01-28 00:26:40

标签: ruby-on-rails ruby-on-rails-3 api oauth

我正在尝试使用公共API实现一种服务,其访问控制模式与facebooks graph api非常相似。我正在使用门卫宝石,它允许我使用Devise进行OAuth,并且还可以轻松地授予访问令牌的权限/范围。

除此之外,我需要: - 基于访问令牌范围的访问控制 - 平台上不同群组用户的访问控制(如facebook上的隐私设置) - 访问控制必须是动态的,不能承担固定的角色

不,我确实看过似乎基于角色的访问控制的CanCan,但它似乎并不容易使OAuth陷入困境,所以我问自己,推出自己的系统是否最好?那么基本上是对模型进行所有访问控制的正确方法吗?

你还有其他建议吗?

1 个答案:

答案 0 :(得分:0)

我认为CanCan可以处理你想要的东西。由于您没有提供有关用户认可的内容的详细信息,因此我将向您展示一些我认为有用的方法。我要说的第一件事是你可以将你想要的任何对象传递给你的能力文件。为此,请执行以下操作:

def ApplicationController < ActionController::Base
  def current_ability
    @current_ability = CustomAbility.new(pass, in, anything, here)
  end
end

在app / models中定义custom_ability.rb:

def CustomAbility 
  include CanCan::Ability

  def initialize(anything, you, want, here)
    ...
  end
end

在这种情况下,any = pass,you = in,want = anything,here = here。此外,您可以在要授权的资源上调用某些方法。 CanCan的工作原理是加载@resource_name,然后输入要授权的能力文件。它通过假设RESTful路由加载@resource_name,但是您可以轻松地使用before_filter加载您自己的资源,只要您将其存储在@resource_name中(即将用户存储在@user中)。

您还可以在要授权已创建参数的对象上调用某些方法。例如,您可能想要这样做:

def initialize(user)
  can :read, Post do |post|
    !((post.readable_groups & user.groups).empty?)
  end
end

基本上,如果该块中的一行返回false,那么您将变为未授权。唯一需要注意的是,块不是在create或new上执行的。有办法解决这个问题。例如,假设您使用唯一性验证在模型级别中为每个用户强制执行一个帖子。您可以使用前置过滤器来加载设置user_id的帖子,然后执行

can :create, Post, valid?: true

无论如何,希望有所帮助。