Rails 用户访问插件

发布于 2024-07-10 03:26:07 字数 372 浏览 5 评论 0原文

有很多处理用户权限的 Rails 插件。 hobo gem 中的实现给我留下了深刻的印象,但我不确定是否可以仅使用此功能而不使用其他部分。 GateKeeper 是一个非常聪明的实现,但有一些错误,尽管它足够小,我可能可以自己修复它。 Restful_ACL 为您提供了一个用于检查创建的类方法,这意味着您无法对相关实例进行任何检查(不确定它是否进行作用域查找)。

我想要提供 ActiveRecord#find 范围版本的东西,它只查找允许当前用户看到的内容。 这应该足够强大,可以说您只能看到您或您的朋友之一拥有的画廊中的图片。

作为奖励,它可以防止您无权执行的创建或更新(在 before_* 或验证步骤中),包括将您自己的记录与不同的用户或图库关联,或创建此类记录。

There are a lot of rails plugins out there that handle user permissions. I'm impressed with the implementation in the hobo gem, but I'm not sure if I can use just this feature and not the other parts. GateKeeper is a really clever implementation, but has some bugs, though it's small enough I could probably fix it myself. Restful_ACL gives you a class method for checking creation, meaning you can't do any checks on the instance in question (not sure if it does scoped finds).

I'd like something that provides a scoped version of ActiveRecord#find which only finds things the current user is allowed to see. This should be robust enough to say, you can only see pictures that are in galleries that are owned by you or one of your friends.

As a bonus, it could prevent creates or updates (in a before_* or validation step) that you don't have the right to perform, including associating your own records with a different user or gallery, or creating such records.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

北方的巷 2024-07-17 03:26:07

您可以使用 declarative_authorization 插件在模型级别执行一些非常复杂的授权技巧。 尽管如此,我自己更喜欢 rails-authorization-plugin - 就这个您定义模型级别的角色(例如,某人是资源的所有者)和控制器级别的权限(例如,只有资源的所有者或管理员才能获取资源)。 我发现这种方法更加简洁,特别是如果您追求干净的 REST 方法。 如果您有这样的请求:

GET /posts

您真正应该返回的是所有帖子,而不仅仅是当前用户的帖子。
为此,您应该有不同的路线:

GET /users/:user_id/posts

其中 :user_id 设置为当前用户的 ID。
然后,这种差异应该反映在适当的操作中:

def index
  user = User.find(params[:user_id]) unless params[:user_id].blank?
  @posts =
   if user
    # get all posts of a user
    user.posts.all
   else
    # get all posts 
    Post.all
   end
end

现在,您真正拥有的是两个授权上下文 - “获取用户的所有帖子”和“获取所有帖子”,并且您通常希望为两者设置不同的权限(例如, “只有管理员才能获取所有帖子”和“只有用户自己或管理员才能获取用户的所有帖子”)。

You can do some really complex authorization tricks on the model level with declarative_authorization plugin. Nevertheless, I myself prefer rails-authorization-plugin - with this one you define the roles on the model level (eg. someone is an owner of a resource) and the permissions on the controller level (eg. only the owner of a resource or admin can get the resource). I find this approach much more concise, especially if you are pursuing for a clean REST approach. If you have request like this one:

GET /posts

what you really should return is all posts, not just the posts of the current user.
For that purpose you should have a different route:

GET /users/:user_id/posts

where :user_id is set to current user's id.
This difference should then be mirrored in the appropriate action:

def index
  user = User.find(params[:user_id]) unless params[:user_id].blank?
  @posts =
   if user
    # get all posts of a user
    user.posts.all
   else
    # get all posts 
    Post.all
   end
end

Now, what you really have here are two authorization contexts - "get all posts of a user" and "get all posts" and you usually want to set different permissions for both (eg. "only admins can get all posts" and "only user it self or an admin can get all posts of a user").

宁愿没拥抱 2024-07-17 03:26:07

我有一个 gem,它完全能够根据对象的角色指定对象的权限。 您可以在这里查看: http://github.com/nakajima/roleful/tree/master 。 它非常适合您暗示的那种 before_filter 方法。

至于只允许用户访问与他们有某种关系的事物,我认为您正在寻找 Rails 关联代理的主要候选者。 我喜欢 Milan Novota 的片段,尽管我会稍微修改一下:

def index
  @posts = user_repo.posts
end

private

def user_repo
  # find_by_id is **much** faster than regular find,
  # plus it just returns nil when there's no record
  if user = User.find_by_id(params[:user_id])
    # returns the association proxy
    user.posts
  else
    # returns the class
    User
  end
end

I have a gem that's entirely about being able to specify permissions for objects based on their role. You can take a look here: http://github.com/nakajima/roleful/tree/master. It would work well for the sort of before_filter approach you hinted at.

As for only allowing users to access things with which they have some sort of relationship, I'd think that you're looking at a prime candidate for Rails association proxies. I like Milan Novota's snippet, though I'd modify it slightly:

def index
  @posts = user_repo.posts
end

private

def user_repo
  # find_by_id is **much** faster than regular find,
  # plus it just returns nil when there's no record
  if user = User.find_by_id(params[:user_id])
    # returns the association proxy
    user.posts
  else
    # returns the class
    User
  end
end
未蓝澄海的烟 2024-07-17 03:26:07

您可以查看锁定。 我还没有在项目中实现这一点,但它可以为您节省一些工作。

You could check out lockdown. I haven't implemented this on project yet but it could save you some work.

为人所爱 2024-07-17 03:26:07

回想起来,我只会使用 Hobo 模式。 这是最简单、最灵活的。

In retrospect, I will just use the Hobo pattern. It is the simplest and most flexible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文