Devise: Force logout for specific user

Created on 26 Jun 2020  路  8Comments  路  Source: heartcombo/devise

Environment

  • Ruby 2.7.0
  • Rails 6.0.3
  • Devise 4.7.2
  • Warden 1.2.3

Current behavior

Can't destroy session for specific user.

I want to logout users on-demand through a controller request:

class MyController < ApplicationController
  def update
    user = User.find(some_id)
    sign_out(user) 
  end
end

The method sign_out always destroy the current_user session, not the session for the specific user I sent as parameter

If I check the session a little bit

scope = Devise::Mapping.find_scope!(User.find(some_id))
> :user

user = warden.user(scope: scope, run_callbacks: false) # If there is no user
> current_user object

users = Devise.mappings.keys.map { |s| warden.user(scope: s, run_callbacks: false) }
> [current_user object] 路 as array

Expected behavior

Destroy session for a specific user instead of the current_user

Note: Session should be destroy for the specific user

All 8 comments

Would be a very useful feature.

Curious, why would you need that?

Curious, why would you need that?

So the admin can log out users.

Why would admin need to logout users? If for some misbehaving, why not to ban?

Lots of reasons:

  • applying an upgrade and want data to freeze
  • banning a user will only take effect when they next log in
  • account could be hacked
  • many accounts could be hacked but you don't know which ones
  • user has paid for a timed period and now it is over

This kind of feature is common in business software, eg: SAP, Oracle etc.

Thanks for answers. Haven't seen a need for this before.

applying an upgrade and want data to freeze

Looks like a hack - user can relogin. Better to implement read only mode for the site.

banning a user will take effect when they next log in

Yes, but better to add a before_action :check_not_banned to ApplicationController (or something like that) or even a middleware

account could be hacked
many accounts could be hacked but you don't know which ones

If the session_id only (not credentials) was stolen, then yes, this will be a solution. But when credentials - then other methods would be better employed, like freezing an account and asking an account holder to reset the password.

user has paid for a timed period and now it is over

Hack 馃槃 Not a proper way of doing this.

Currently, some workaround can be implemented. For example, adding session_id to users table and whenever user logins - update this column. When you want to logout him - set this to null. And when he makes a request with old session_id in cookies, but the value in the database is null - assume he is not logged in.

@seanfcarroll thank you so much for the help explaining the possibles scenarios where a force logout process can be useful, your examples are really good.

@fatkodima you are totally right, a better way to handle this feature is outside devise. We implemented sessions to check if the user has an active session "user is logged in".

Was this page helpful?
0 / 5 - 0 ratings