如何限制对UI功能的访问?

时间:2018-01-17 21:42:16

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

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

这是您典型的SaaS模式,根据用户订阅的级别,可以逐步提供更多功能。

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

我正在写信询问是否有一个众所周知的实现模式,在我推出自己的实现模式之前我还没有意识到。

以下是基于订阅级别限制的不同类型的事物:

  1. 可通过图标访问的功能
  2. 可通过菜单项访问的功能
  3. 某些报告(每个报告都有一个定义它的ReportDefinition。)
  4. 某些上传(每个上传都有一个定义它的FileType。)
  5. 某些BackgroundProcesses(每个都有一个定义它的ProcessType。)
  6. 每个订阅都有一个计划。将该计划与上面的第3,4和5项联系起来很简单,并cancancan使用current_user来获取可访问性。但是,功能1和2是不同的故事。我可以看到在查看功能/计划列表的视图助手中包装其可访问性。但那只能处理视图。如果用户知道该URL,他们仍然可以通过直接键入URL来访问该功能。在这种情况下,我是否需要在控制器操作级别再次处理授权,或者是否可以使用某种中间件来限制功能的可访问性?

    非常感谢。

3 个答案:

答案 0 :(得分:2)

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

然后,在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

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

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 %>

这当然不是安全性(仅限视图层更改),这就是为什么我也使用我之前提出的方法从控制器返回的原因:

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

对于上面的例子,不要忘记使用return ,否则代码将继续执行。

对于非常简单的事情,我使用Pundit

答案 1 :(得分:1)

我会简单地使用枚举来设置不同的访问或订阅级别。然后只需编写一个名为before_action的{​​{1}}来阻止整个操作。然后我会在视图中设置一些条件或view_helpers来阻止对某些UI元素的访问。

答案 2 :(得分:0)

https://github.com/jnunemaker/flipper是一个很好的解决方案,可以完全满足您的需求。

否则,就像你说的那样,cancancan对于天真的解决方案是有益的。