13

我对 rails (3) 比较陌生,并且正在使用 CanCan 构建一个应用程序,其中有 3 层用户。

  • 访客 - 未注册访客用户
  • 注册并登录访客
  • 管理员 - 使用管理员标志注册并登录的访客

我现在的能力很糟糕,从 cancan 文档中复制而来,基本上定义了访客角色和管理员角色

class Ability

    include CanCan::Ability

    def initialize(user)
        user ||= User.new # Guest user

        if user.is_admin?
            can :manage, :all
        else
            can :read, [Asana,Image,User,Video,Sequence]
        end
    end

end

我正在寻找添加用户角色。由于我正在创建那个一次性用户模型,我考虑过使用 new_record?确定用户是否登录。就像是:

class Ability

    include CanCan::Ability

    def initialize(user)
        user ||= User.new # Guest user

        if !user.new_record? and user.is_admin?
            can :manage, :all
        elsif !user.new_record? and !user.is_admin?
            can {registered user-y permissions}
        else
            can :read, [Asana,Image,User,Video,Sequence]
        end
    end

end

但是,就是感觉不对。似乎有点与实际登录无关,并且担心它是否真的安全。

寻找有关更优雅的方法的建议。

谢谢!

4

5 回答 5

22

好问题,我使用从低到高权限的方法:

class Ability  
  include CanCan::Ability  

  def initialize(user)
    # Guest User 
    unless user 
      can :read, [Asana,Image,User,Video,Sequence]
    else
      # All registered users
      can {registered user-y permissions}
      # Admins 
      if user.is_admin?
        can :manage, :all
      end
    end 
  end  
end

这样,如果明天你有其他角色要集成,你可以添加一个 case 语句,如下所示:

class Ability  
  include CanCan::Ability  

  def initialize(user)
    # Guest User 
    unless user 
      can :read, [Asana,Image,User,Video,Sequence]
    else
      # All registered users
      can {registered user-y permissions}
      # Different roles
      case user.role
      when 'admin'
        can :manage, :all
      when 'manager'
        can :manage, [Video, Image, Sequence]
      end
    end 
  end  
end
于 2011-03-24T10:10:03.130 回答
2

所以你基本上想要的是没有登录用户的能力,登录用户的能力,然后是登录管理员的能力?

因为当前用户模型被传递到初始化中,所以您必须根据用户的属性进行测试,并且使用存储在用户模型上的基本角色属性是有意义的,例如

def initialize(user)
user ||= User.new # guest user (not logged in)
if user.role == 'admin'
  # Admin roles
  can :manage, :all
elsif user.role == 'user'
  # Signed in user permissions
else
  # Guest permissions
  can :read, :all
end

结尾

因此,当用户注册/注册时,您可以将角色值默认为“用户”,然后允许使用某种方法在管理界面中将其更新为“管理员”。您可以使用单个管理员吗?检查用户,因为这对于来宾以及正常登录的用户来说都是错误的。

于 2011-03-21T13:14:43.523 回答
1

如果您使用角色继承,则此模式效果很好:

能力

user ||= User::GUEST # guest user (not logged in)

# anyone
can [:read], Post

# any registered user
if user.role? :user
  can [:comment], Post
end

# editor
if user.role? :editor
  can [:create], Post
end

# admin
if user.role? :admin
  can [:manage], Post
end

用户

GUEST = User.new.tap {|u| u.role = 'guest'}

ROLES = %w[guest user editor admin]
def role?(base_role)
  begin
    ROLES.index(base_role.to_s) <= ROLES.index(role.to_s)
  rescue
    raise "invalid role query '#{base_role}' against user role '#{role}'"
  end
end
于 2013-04-11T21:55:52.257 回答
1

如果用户对象不是 new_record,则表示它存储在数据库中。对我来说,这足以接受它是一个登录用户。

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new  

    # Guest users
    can :create, User

    # Members  
    unless user.new_record?
      can [:edit, :update], User, :id => user.id
    end

    # Admins
    if user.admin?
      can :manage, :all
    end
  end
end

此外,有时管理功能不必如此花哨 - 也许这就是您所需要的?

class User < ActiveRecord::Base
  # Alternatively, you can add an admin attribute flag
  def admin?
    ["theadmin@yourservice.com", "hisspouse.yourservice.com"].include?(email)
  end
end

最后,虽然您是 Rails 新手,但我建议您从头开始编写自己的身份验证代码。使用像 Devise 和 Authlogic 这样的 gem 似乎总是有它的缺点。而且它实际上不必那么复杂。Ryan(cancan 的作者)就这个话题做了一个很棒的截屏视频:http ://railscasts.com/episodes/250-authentication-from-scratch

于 2011-03-22T07:21:41.287 回答
0

如果您实际上有一个持久用户模型,那么这是一个登录用户,否则他们是一个访客。也许你是在想这个?

class Ability
  include CanCan::Ability

  def initialize(user=nil)
    if user && user.is_admin?
      can :manage, :all
    elsif user
      can {registered user-y permissions}
    else # guest
      can :read, [Asana,Image,User,Video,Sequence]
    end
  end
end
于 2011-03-22T04:23:20.457 回答