【问题标题】:Devise force logout for some users from Rails App从 Rails 应用程序为某些用户设计强制注销
【发布时间】:2017-02-04 07:22:43
【问题描述】:

是否可以通过 Devise 强制部分用户注销。

在我的设置中,我使用 Rails 4.1.15 和 Devise 1.5.4。会话保存在数据库中,并且没有与用户 ID 的直接映射。是否有一种设计方法可以针对某些用户而不是全部注销。

我尝试将密码重置为代理,该代理会立即注销,但并非总是如此。

user_obj.update_attributes(:password => "some_random_string")

【问题讨论】:

  • 你需要在控制器或rails控制台中做吗?
  • 在控制器中,例如,管理员将能够为不是他自己的用户列表删除/取消会话?并且会话数据库中有数百万条记录无法迭代以删除 10 个用户的会话。

标签: ruby-on-rails ruby session ruby-on-rails-4 devise


【解决方案1】:

我可以为您推荐下一个解决方案。

admin 添加一个名为force_logout:boolean 的新列

在您的任何控制器中添加一个新操作以将force_logout 设置为true。例如:

# in admins_controller.rb

def force_logout
  admin = Admin.find(params[:id])
  admin.update_column(:force_logout, true)
  redirect_to :back
end

如果force_logouttrue,则在application_controller.rb 中添加before_action 以注销用户

before_action :check_force_logout

def check_force_logout
  if current_user && current_user.force_logout?
    current_user.update_column(:force_logout, false)
    sign_out(current_user)
  end
end

您也需要在管理员登录后重置force_logout 列。通常您可以在操作create 中执行session_controller.rb

【讨论】:

  • 上述解决方案不会立即注销,它会在用户下次尝试登录时,这是我不想要的。我只想删除他们当前的活动会话,而不是用户下次尝试登录的会话。我不想删除将强制注销字段设置为 true 后创建的会话。
  • 不,每个请求都会调用check_force_logout,并将立即注销。可能需要在sign_out()之后添加重定向
  • 是的,正如我上面提到的,它会起作用。但我想破坏活动的会话。即使真正的登录尝试从具有全新会话的不同浏览器打开,您的上述解决方案也会失败,因为该标志仍设置为 true。我不想等待下一个请求到达。我想在管理员级别做。
  • 当使用 websoskets 通知客户端应用程序/浏览器删除会话的 cookie 并重新加载页面时。
【解决方案2】:

是时候挖掘这个了。我能够解决此问题的唯一方法是访问会话。它很慢,但它有效。

  def sign_out_different_user
    @user = User.find(params[:id])
    sessions = ActiveRecord::SessionStore::Session.where("updated_at > ?", Time.now - 480.minutes).all
    sessions.each do |s|
      if s.data['user_email'] == @user.email
        s.delete and return
      end
    end
  end

出于我的目的,我需要更改用户对象的会话过期时间,因此我也将其添加到方法中。 YMMV

 @user.session_expires_at = Time.now
 @user.save

【讨论】:

    猜你喜欢
    • 2015-05-10
    • 2019-04-04
    • 1970-01-01
    • 2015-09-21
    • 2015-09-27
    • 2013-10-20
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多