Where to override current_user helper method of devise gem

前端 未结 4 1765
耶瑟儿~
耶瑟儿~ 2020-12-13 00:31

How can i override current_user of devise gem. Actually I need to add web services for mobile-app.

Currently devise is managing session and \'current_

相关标签:
4条回答
  • 2020-12-13 01:10

    Limbo-Peng's answer is great, but can be improved a little to make sure only admins can do this:

    You'll need to also define a is_admin? method or is_admin attribute on the User class.

    You may also want to use a different key than user_id, so it will never conflict with your regular parameters.

    # 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
    
    0 讨论(0)
  • 2020-12-13 01:19

    Assuming we can trust our session data (which relies on whether you put user input in there without proper authorization or not), this might work as a Concern:

    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
    

    I'm using this in a project for now.

    A minor question (in the answer, sorry) ... should I be aware of any changes in Devise or Warden that make devise_current_user above outdated?

    0 讨论(0)
  • 2020-12-13 01:23

    The other answer suggesting aliasing the method is actually not the best solution. Doug English's comment is the best solution:

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

    Here's the reason:

    Suppose you're including your ApplicationHelper in your controller. If you need a method in your ApplicationHelper that relies on devise_current_user, given the alias solution inside the controller, you're out of luck.

    But with the explicit method definition above, you can move the definition to the helper and call it from other methods and you still get to include it in the controller.

    This is useful, for example, when you're developing a user impersonation solution and you need to show two different users in the view, one for the real admin (devise_current_user) and the other, the impersonated user (current_user).

    0 讨论(0)
  • 2020-12-13 01:27

    According to the module Devise::Controllers::Helpers, current_user (together with all other devise helpers) is added to ApplicationController, which means that you can override it in this way:

    # in application_controller.rb
    
    def devise_current_user
      @devise_current_user ||= warden.authenticate(scope: :user)
    end
    
    def current_user
      if params[:user_id].blank?
        devise_current_user
      else
        User.find(params[:user_id])
      end   
    end
    
    0 讨论(0)
提交回复
热议问题