22

我该如何覆盖current_userdevise gem。 其实我需要为移动应用程序添加web服务。在哪里可以覆盖设计gem的current_user帮手方法

当前设计是管理会话和'current_user'为web应用程序。

现在移动应用程序将发送user_id到服务器。我需要覆盖像这样的当前用户

def current_user 
    if params[:user_id].blank? 
    current_user 
    else 
    User.find(params[:user_id]) 
    end 
end 

我是否需要修改devise gem作为插件?或者是其他东西 ?
请详细解释一下,因为我是新手。

亲切的问候,

+2

yikes ...所以,你是说当一个移动代理发送一个user_id你会信任它吗? – 2012-04-27 16:18:08

+0

还有一些身份验证密钥 – 2012-04-29 09:51:21

+0

Devise会处理那个token_authenticatable - 只是传递authentication_token,不需要user_id。 – 2012-04-30 16:01:43

回答

46

根据模块Devise::Controllers::Helperscurrent_user(与所有其他色器件助手一起)添加到ApplicationController中,这意味着你可以用这种方式重写它:

# in application_controller.rb 
alias_method :devise_current_user, :current_user 
def current_user 
    if params[:user_id].blank? 
    devise_current_user 
    else 
    User.find(params[:user_id]) 
    end 
end 
+8

“alias_method”行上的错误:当启动我的环境时,类ApplicationController(NameError)的undefined_method'current_user'。如果我注释掉它,启动并取消注释,它可以正常工作。有解决办法吗? – Frexuz 2012-10-31 18:26:01

+5

Frexuz,尝试替换alias_method类似的东西: def devise_current_user {@devise_current_user || = warden.authenticate(:scope =>:user)} – 2013-03-16 04:37:54

+0

是线程安全的吗?在核磁共振成像后,我在控制器中的奇怪点出现无错误。 – 2014-04-12 01:24:58

5

的其他回答暗示别名方法实际上并不是最好的解决方案。道格英语的评论是最好的解决办法:

# In ApplicationHelper 
def devise_current_user 
    @devise_current_user ||= warden.authenticate(:scope => :user) 
end 

这里的原因:

假设你包括你的控制器在ApplicationHelper。如果您的ApplicationHelper中需要一个依赖devise_current_user的方法,那么给定控制器内的别名解决方案,那么您运气不好。

但是,通过上面的显式方法定义,您可以将定义移动到助手并从其他方法调用它,并且仍然可以将其包含在控制器中。

这很有用,例如,当您开发用户模拟解决方案时,您需要在视图中显示两个不同的用户,一个用于真实管理员(devise_current_user),另一个用户模拟用户(current_user) 。

+2

确实,你是对的。请注意,ApplicationController中应包含以下内容:'include ApplicationHelper'。否则,'devise_current_user'变得未知。 – 2015-09-21 10:37:22

0

假设我们可以信任我们的会话数据(这依赖于是否让用户输入有未经适当授权或没有),这可能工作作为关注:

module Concerns 
    module ControllerWithImpersonation 
    extend ActiveSupport::Concern 

    included do 
     helper_method :devise_current_user 
    end 

    def current_user 
     if session[:impersonated_user_id].blank? 
     devise_current_user 
     else 
     User.find(session[:impersonated_user_id]) 
     end 
    end 

    def devise_current_user 
     @devise_current_user ||= warden.authenticate(:scope => :user) 
    end 

    end 
end 

我在使用本项目现在。

一个小问题(在答案中,对不起)...我应该知道设计师或监工的任何变化,使devise_current_user以上过时?

0

凌波鹏的回答是伟大的,但可以提高一点,以确保只有管理员可以这样做:

你还需要定义一个is_admin?方法或User类is_admin属性。

您可能还想使用与user_id不同的密钥,因此它永远不会与常规参数发生冲突。

# to impersonate another user, e.g. for customer support 
# only admins can do this.. 
# 
alias_method :devise_current_user, :current_user 
def current_user 
    if ! params[:user_id].blank? \ 
    && devise_current_user && devise_current_user.is_admin? 
    User.find(params[:user_id]) 
    else 
    devise_current_user 
    end 
end 
相关问题