ruby-on-rails - 如何限制对 UI 功能的访问?

标签 ruby-on-rails ruby-on-rails-4 ruby-on-rails-4.2

我过去曾使用声明性授权 gem,如 cancancancancan 来控制对数据的访问。但是,在这个新应用程序中,我试图控制对实际功能的访问。

这是典型的 SaaS 模型,其中根据用户订阅的级别逐渐提供更多功能。

大多数功能都可以通过单击整个应用程序中的不同图标或菜单项来使用。

我写信是想询问在我自己动手之前是否有一个我不知道的众所周知的实现模式。

以下是根据订阅级别限制的不同类型的内容:

  1. 可通过图标访问的功能
  2. 可通过菜单项访问的功能
  3. 某些报告(每个报告都有定义它的 ReportDefinition。)
  4. 某些上传(每个上传都有一个文件类型定义。)
  5. 某些 BackgroundProcesses(每个都有一个定义它的 ProcessType。)

每个订阅都有一个计划。将该计划与上面的第 3、4 和 5 项联系起来并使用 cancancan 以供 current_user 访问非常简单。但是,功能 1 和 2 是另一回事。我可以看到将它们的可访问性包装在检查功能/计划列表的 View 助手中。但这只处理 View 。如果用户知道 URL,他们仍然可以通过直接输入 URL 来访问该功能。在这种情况下,我是否需要在 Controller 操作级别再次处理授权,或者我是否可以放入某种中间件来限制对这些功能的访问?

非常感谢。

最佳答案

如果它是一个简单的应用程序,我只需在 User 上添加一个 admin 列。如果有超过 2 种用户类型(admin/non-admin/author/editor/etc),那么我会将其设为 Enum 字段而不是 bool 值。

然后,在 user.rb 中我添加了几个方法...

def is_admin?
  admin?
end

def is_author?
  !admin?
end

从那里,我还在 application_controller.rb 中添加了一些引发异常的代码:

def unauthorized
  head(:unauthorized)
end

def unprocessable
  head(:unprocessable_entity)
end

我还在application_controller.rb中添加了一个current_user方法:

helper_method :current_user

def current_user
  @user ||= User.find(session[:user_id])
end

然后在我看来,这就是我处理“隐藏”事物或禁用按钮的地方。

<%= if current_user.is_admin? %>
  <button>Admin button</button>
<% else %>
  <button>Author button</button>
<% end %>

这当然不是安全性(仅 View 层更改),这就是为什么我也使用我之前布置的方法提前从 Controller 返回:

def destroy
  return unauthorized unless current_user.is_admin?
  # ... delete code here
end

对于上面的例子不要忘记使用return否则代码会一直执行。

对于比较简单的事情,我使用 Pundit .

关于ruby-on-rails - 如何限制对 UI 功能的访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48310464/

相关文章:

mysql - ActiveRecord 资源的多个不同计数

ruby-on-rails - Rails 3 - 如何测试 Controller 模块?

ruby-on-rails - 当遇到在早期版本的 Rails 中使用 attr_accessible 的情况时,Rails 4 中的禁止属性错误

ruby-on-rails-4 - 使用 capistrano 3 部署到 Unicorn 服务器时出错

mysql - El Capitan 升级 : Library not loaded:/usr/local/lib/libmysqlclient. 18.dylib

ruby-on-rails - 使用 ActiveJob,perform_now 的结果似乎与 perform_later 不同

ruby-on-rails - 如何通过关联(具有中介模型的值)为多对多设置固定装置?

ruby-on-rails - 在 Ruby On Rails 中创建模板并动态替换占位符

ruby-on-rails - 在 Ruby 中获取 self 作为父级中的调用类

mysql - 添加refinerycms gem后迁移数据库的问题