Ruby on rails 按用户id查找并终止所有活动会话

Ruby on rails 按用户id查找并终止所有活动会话,ruby-on-rails,session,session-cookies,Ruby On Rails,Session,Session Cookies,我在Rails 6应用程序上使用基于cookie的会话,设置如下: Rails.application.config.action_dispatch.cookies_serializer = :marshal Rails.application.config.session_store :cookie_store, expire_after: 14.days 用户更改密码后,我希望终止其所有活动会话,这些会话可能位于其他浏览器和/或设备中。大概是这样的: ActionDispatch::Ses

我在Rails 6应用程序上使用基于cookie的会话,设置如下:

Rails.application.config.action_dispatch.cookies_serializer = :marshal
Rails.application.config.session_store :cookie_store, expire_after: 14.days
用户更改密码后,我希望终止其所有活动会话,这些会话可能位于其他浏览器和/或设备中。大概是这样的:

ActionDispatch::Session::CookieStore.where(user_id: session[:user_id]).destroy_all

对于
CookieStore
,只有这些方法不是真正有效的方法。您知道如何实现这一点吗?

不幸的是,无论会话存储方式如何,您都无法通过会话实现这一点

要做到这一点,您必须将服务器上的活动登录列表保存在单独的DB表中,并删除这些记录,例如:

您可以创建新表,例如
logins
,其中包含
user\u id
token
列。每次用户登录时,您将在此表中创建新记录,然后将
user\u id
token
保存到会话:

def登录
# ...
#用户授权码
# ...
login=user.logins.create(令牌:SecureRandom.uuid)
会话[:user\u id]=login.user\u id
会话[:用户\令牌]=login.token
结束
每次从会话加载用户时,必须执行两个步骤:

  • 按ID查找用户
  • 检查用户令牌的有效性
  • 现在,每次您想注销用户时,只需从登录表中删除相应的记录

    在您希望从所有其他设备注销用户的情况下,您只需执行以下代码:

    authorized\u user.logins.where.not(令牌:会话[:user\u令牌])。全部删除
    
    你就完了

    当然,这只是一个简单的例子,您还可以对令牌进行哈希或加密,这样它们就不能直接读取,或者您可以添加过期日期,并在超过日期时自动注销用户,等等

    def authorized_user
      @authorized_user ||= begin
        login = Login.find_by(user_id: session[:user_id], token: session[:user_token])
        return if login.blank?
        
        login.user
      end
    end