Rails Devise 认证用户未起作用

5

我是Ruby on Rails的新手,目前想要使用Devise gem来实现身份验证系统。该系统需要只有管理员可以列出用户并创建新用户。(我通过向Devise生成的User模型添加admin布尔字段来添加管理员角色)。我使用Rails 3.2,Ruby 1.9.3和最新的Devise gem。

然而,下面列出的代码无法阻止未经身份验证的用户访问特定操作(索引,新建和创建)。

# 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 
authenticate_user! 方法不能正常运行(例如,未经身份验证的用户仍然可以访问 /users/users/sign_up),但也不会引发任何异常。我查了一些资料,但还是无法解决这个问题,请帮忙。

PS. 对不起,我的英语不好。

更新

感谢所有回答。我将根据指示更新is_admin使其正常工作。

但主要问题在于,在第一次使用authenticate_user!过滤器时,未登录的用户便能够通过(并且在is_admin方法中引发异常,因为此处的current_user将为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] 

很抱歉没有表达清楚。


使用 CanCan gem。 - Hauleth
3个回答

4

以下为Devise官方文档内容:

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


(注:before_filter为Rails中的过滤器,用于在执行action前先执行某些处理)
before_filter :authenticate_user!

要验证用户是否已登录,请使用以下辅助功能:
user_signed_in?

对于当前已登录的用户,可以使用以下辅助程序:
current_user

因此,:authenticate_user! 只会使控制器上的所有其他帮助程序可用(前提是将其放入:before_filter中),但仍然需要您定义签署/未签署用户的逻辑!请记住,Devise是一个身份验证解决方案,而不是授权解决方案。如果需要处理授权(似乎确实需要),而不编写所有逻辑,请使用类似CanCan这样的东西,它可以很好地与Devise一起使用。

谢谢你:)。我想给这里的每个人投票,但我刚刚注册了这个网站,声望很低,对此感到抱歉。 - Saran S.
据我所知,您在投票方面与我拥有相同的限制。欢迎来到本网站,并不要忘记接受您认为最佳的答案! - bluehallu

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

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

感谢您的快速回复。代码可以重定向非管理员用户(感谢您指出这一点)。但是我的第一个问题是未登录用户可以通过访问索引、新建或创建操作来传递authenticate_user!过滤器(因此在is_admin?上引发异常,因为此处的current_user为空)。无论如何还是感谢您。 - Saran S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接