5

I'm new to Ruby on Rails, currently I want to use Devise gem for authentication system. The system needs to have only Admin can list users and create a new user. (I added admin role by adding admin boolean field to the User model generated by Devise). I use Rails 3.2, Ruby 1.9.3 and the latest Devise gem.

However, the codes listed below do not prevent non authenticated users to access specific actions (index, new, and create).

# users_controller.rb
class UsersController < Devise::RegistrationsController
  before_filter :authenticate_user!, only: [:index, :new, :create]
  before_filter :is_admin, only: [:index, :new, :create]

  def index
  end

  private

  def is_admin
    current_user.admin?
  end
end

==

# config/routes.rb
App::Application.routes.draw do
  root to: 'static_pages#home'

  get '/about', to: 'static_pages#about'

  devise_scope :user do
    get '/users', to: 'users#index'
  end

  devise_for :users, controllers: { sessions: "sessions", registrations: "users" }
end 

The authenticate_user! method does not work (for example, non authenticated users can still access to /users or /users/sign_up) but also does not raise any exceptions. I did some searching but have no ideas why. Please help.

PS. Sorry for my English.

UPDATE

Thanks for all answers. I will update is_admin to correctly working as pointed out.

But the main problem here is that non logged in users can pass authenticate_user! filter in the first place (and raise exception on is_admin method since current_user here would be nil).

# Here non logged in users does not redirect to sign in page when access to,
# for example, /users or /users/sign_up.
before_filter :authenticate_user!, only: [:index, :new, :create] 

Sorry for being not obvious.

4

3 回答 3

4

从设计文档:

Devise 将创建一些助手以在您的控制器和视图中使用。要设置具有用户身份验证的控制器,只需添加此 before_filter:

before_filter :authenticate_user!

要验证用户是否已登录,请使用以下帮助程序:

user_signed_in?

对于当前登录的用户,此帮助程序可用:

current_user

所以,:authenticate_user!只会使控制器上的所有其他助手可用(前提是您将其放入 :before_filter),但定义签名/未签名用户的逻辑仍然是您的责任!

请记住,Devise 是一种身份验证解决方案,而不是授权解决方案。如果您需要处理授权(看起来像您这样做)而不自己编写所有逻辑,请使用 CanCan 之类的东西,它与 Devise 一起工作得很好。

于 2013-07-01T11:40:43.293 回答
1

显然,您需要检查有效的会话用户,然后按以下步骤进行操作..

def is_admin
  if current_user.nil?
    redirect_to_some_path
  else
    if current_user.admin?
      true
    else
      redirect_to some_path
    end
  end
end
于 2013-07-01T11:08:51.953 回答
0

使用方法if..else声明is_admin

before_filter :authenticate_user!, only: [:index, :new, :create]
before_filter :is_admin, only: [:index, :new, :create]

private

def is_admin
 if user_signed_in?
  if current_user.admin?
    true
  else
    redirect_to some_path
  end
 else
   redirect_to login_path
 end
end
于 2013-07-01T10:24:57.327 回答