如何通过Devise添加管理限制功能到我的rails应用程序?

时间:2014-11-25 02:31:55

标签: ruby-on-rails authentication ruby-on-rails-4 devise

我的rails应用程序有几个出租车操作员,他们有一些出租车,它们的关联如下:

class Operator < ActiveRecord::Base
    has_many :cabs
end

我希望添加身份验证系统,以便为每个运营商创建管理员。我正在使用Devise。由于我需要创建路径为:operator /:operator_id / admins / sign_up,我生成了Admin模型,如:

rails generate devise Admin

然后我修改了路线以获得上述路径:

scope "operators/:operator_id" do 
    devise_for :admins
end

经过多次修改后,我能够添加新的管理员并将其与相应的运营商相关联。但是,我想确保管理员只能访问与管理员关联的运营商的cab。将以下内容添加到cabs_controller不起作用:

before_action :authenticate_admin!

作为signed_in管理员可以访问所有其他运营商的出租车。我想确保:

1. If there is no current_admin, my app asks to sign_in or sign_up
2. If there already is a current__admin signed_in, he/she has access to only the cabs associated to that operator to which the current_admin is assigned.

我是Devise的新手。请告知我应该如何进行。谢谢!

4 个答案:

答案 0 :(得分:0)

Devise用于身份验证,您的问题是Devise无法帮助的授权问题。您可以查看Cancan https://github.com/ryanb/cancan:)

答案 1 :(得分:0)

您不需要为管理员设定范围。我不确定它是否可以解决任何访问问题。它还使您的代码难以维护。

我建议你专注于关系

class Operator < ActiveRecord::Base
    has_many :cabs
    has_many :admins
end


class Operator < ActiveRecord::Base
    has_many :cabs, through: operator
    belongs_to :operator
end

通常我以后处理这种情况的方法是在cab模型中编写特殊内容:

  def is_admin?(admin)
      admin.cabs.include?(@cab)
      # you can put more logic here if you have different levels of access
  end

以及稍后在控制器中要限制访问时:

  if @cab.is_admin?(current_admin) 
     # do the stuff
  else
     # go away message
  end

或者例如,如果您在索引中列出cab:

  def index 
     current_admin.cabs.page(params[:page]) # this is assuming you're using pagination with something like Kaminari
  end 
来自divise的

current_admin,您可能还想运行:authenticate_admin!在过滤之前要确保你有管理员并且它不是

当然你可以把它放在价格信息中并像过滤前一样运行它。

答案 2 :(得分:0)

最简单的解决方案是使用STI并使用Admin&lt;用户,然后是几个

devise_for :users
devise_for :admins

如果您不想使用STI,那么如果您将一个角色方法添加到users表中,那么一些自定义覆盖可能会起到作用。

#routes
devise_for :users
namespace :admin do
  devise_for :admins,
           singular: :admin,
           plural: :admins,
           class_name: 'User',
           only: [:sessions],
           path: '/',
           module: :devise
end 


#lib/overrides/devise
require "devise/strategies/authenticatable"
require "devise/strategies/database_authenticatable"

module Devise
  module Strategies
    class DatabaseAuthenticatable
      def authentication_hash
        if mapping.name == :admin
          @authentication_hash.update(role: :admin) #will add a where(role: :admin) clause
        else
          @authentication_hash
        end
      end
    end
  end
end


class Admin::ApplicationController < ApplicationController
  skip_before_filter :authenticate_user!

  before_filter :authenticate_admin!
end 

答案 3 :(得分:0)

您可以使用角色基础身份验证。

生成用户模型

   class User < ActiveRecord::Base 
     enum role: [:operator, :admin]
     after_initialize :set_default_role, :if => :new_record?

     def set_default_role
       self.role ||= :operator
     end

     # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :trackable, :validatable
   end

生成迁移以添加角色

rails g AddRoleToUser role:integer

请查看ENUM