我正在构建一个使用Salesforce作为数据存储后端的应用程序。这意味着除了User之外,我的数据库中没有模型。我不能使用传统的授权解决方案,因为它们需要我访问rails模型。
我正在构建的应用程序需要围绕用户的某些权限。用户有两种状态: 用户:未激活 用户:激活
我将从Salesforce触发用户状态的更改。
我的视图需要根据用户的状态进行保护。我不确定处理这个问题的最可扩展的方法是用户模型中的简单状态列,并且只有<%= current_user.state ==“激活”%>在我看来还是有更好的解决方案?
谢谢
答案 0 :(得分:5)
您可以使用cancan(cancancan),有一个选项可以让您在控制器上进行授权。
authorize_resource :class => false
您可以在他们的维基上阅读有关此内容的更多信息here是一个开始
答案 1 :(得分:2)
在Rails 4.1中引入的Active Record,Enum的一个新功能是实现您的需求的最简单方法。您可以实现一种非常基本的基于角色的授权形式,其中一个角色“已激活”,具有两种状态。
创建迁移:
$ rails generate migration AddRoleToUsers role:integer
迁移将如下所示:
class AddRoleToUsers < ActiveRecord::Migration
def change
add_column :users, :role, :integer
end
end
将代码添加到您的用户模型以实现枚举:
class User < ActiveRecord::Base
enum role: [:activated, :unactivated]
after_initialize :set_default_role, :if => :new_record?
def set_default_role
self.role ||= :unactivated
end
end
您可以定义角色的名称,如有必要,可以根据需要更改名称(每个用户记录存储的整数值保持不变)。 Active Record会将属性的分配限制为预定义值的集合,因此您不必添加任何代码来将角色的名称限制为已定义的集合。最重要的是,枚举带有一组便捷方法,允许您直接查询角色而无需任何额外的代码。对于名为role的枚举属性,如果值已激活且未激活,则可以使用以下方法:
User.roles # => {"activated"=>0, "unactivated"=>1} # list all roles
user.activated! # make the user activated
user.activated? # => true # query if the user is activated
user.role # => "activated" # find out the user’s role
@users = User.activated # obtain an array of all users who are activated
user.role = 'foo' # ArgumentError: 'foo' is not a valid, we can’t set invalid roles
您可以在控制器中使用条件:
class UsersController < ApplicationController
def index
unless current_user.activated?
redirect_to :back, :alert => "Access denied."
end
@users = User.all
end
end
或者在视图中使用它:
<% if current_user.activated? %>
<li><%= link_to 'Special Reports', some_path %></li>
<% end %>
通常,如果访问控制向控制器添加了大量代码,建议您使用CanCanCan或Pundit,因为您可以将复杂的授权逻辑移动到中心位置与控制器隔离(“瘦控制器”)。但是,如果您的需求与您描述的一样简单,则控制器中基于角色的授权是最佳的。
我写了一篇Rails Pundit教程,比较了这两种方法,并提供了有关基于角色的简单授权以及Pundit基于角色的授权的更多详细信息。