Sign out specific user with Devise in Rails

2020-03-02 10:12发布

问题:

I have Devise for user authentication. I want to sign out a user with a specific id.

in my controller

  def exit
    @user = User.find(5)
    sign_out(@user) # this line here signs out the current_user   
  end

The sign out command of devise, even though I pass the @user, it signs out the current_user. How can I select a user from the database and sign him out with the devise commands?

回答1:

I am assuming this is part of some admin module, where you want to sign out a particular user.

However, this is not easy to solve. Whether or not a user is signed in or not is stored in the session. So to sign out another user, you would have to have access to its session.

Note: afaik the sign_out method only works in the current session, or maybe through warden (do not know warden well enough) it could extend to all sessions this current server has ever touched. However: if you use passenger, or some form of rails server cluster (which is pretty common), afaik this will not work. I would be interested to hear otherwise, with some explanation :) The sign_out uses the given parameter to determine the scope to sign out from in (afaik) the current session.

So what we generally did was add a kind of emergency button to sign out all users: which destroys all sessions. Note this is of course only possible if you use some database or document-store backed session-store.

Alternatively you could open all sessions, and look for the correct session (for your user), and then destroy those sessions.

To read data from a specific session in stored in activerecord, you can write the following:

@session = ActiveRecord::Base.connection.select_all( "SELECT * FROM sessions WHERE session_id = '#{sess_id}'" )
Marshal.load(ActiveSupport::Base64.decode64(@session.data))

There are alternative approaches:

  • use Timeoutable module, and force a timeout for a user?
  • if you use Rememberable you could do @user.forget_me, but I am not sure that this actually affects the current session?


回答2:

from the device api doc http://rubydoc.info/github/plataformatec/devise/master/Devise/Controllers/SignInOut#sign_out-instance_method the sign_out(@user) method should works. Is it possible that the current_user by chance has the id 5?