在 Rails 中使用 Devise 注销特定用户

Posted

技术标签:

【中文标题】在 Rails 中使用 Devise 注销特定用户【英文标题】:Sign out specific user with Devise in Rails 【发布时间】:2014-08-14 18:33:13 【问题描述】:

我有用于用户身份验证的设计。 我想注销具有特定 ID 的用户。

在我的控制器中

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

设计的退出命令,即使我传递了@user,它也会退出current_user。 如何从数据库中选择用户并使用设计命令将其注销?

【问题讨论】:

您是在谈论让用户退出测试还是在您的开发/生产环境中? 目的是什么?你确定@user 会话已设置 devise rememberable module 【参考方案1】:

我假设这是某个管理模块的一部分,您想在其中注销特定用户。

然而,这不容易解决。用户是否登录都存储在会话中。因此,要退出另一个用户,您必须有权访问其会话。

注意:afaik sign_out 方法仅适用于当前会话,或者可能通过warden(不太了解warden)可以扩展到当前服务器曾经接触过的所有会话。但是:如果您使用乘客,或某种形式的 rails 服务器集群(这很常见),afaik 这将不起作用。我很想听听其他的解释 :) sign_out 使用给定的参数来确定在当前会话(afaik)中退出的范围。

所以我们通常做的是添加一种紧急按钮来退出所有用户:这会破坏所有会话。请注意,这当然只有在您使用某些数据库或文档存储支持的会话存储时才有可能。

或者,您可以打开所有会话,查找正确的会话(为您的用户),然后销毁这些会话。

要从存储在活动记录中的特定会话中读取数据,您可以编写以下内容:

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

还有其他方法:

使用Timeoutable 模块,并强制用户超时? 如果你使用Rememberable,你可以使用@user.forget_me,但我不确定这是否真的会影响当前会话?

【讨论】:

【参考方案2】:

来自设备 api 文档 http://rubydoc.info/github/plataformatec/devise/master/Devise/Controllers/SignInOut#sign_out-instance_method 的 sign_out(@user) 方法应该可以工作。 current_user 的 id 是否可能是 5?

【讨论】:

以上是关于在 Rails 中使用 Devise 注销特定用户的主要内容,如果未能解决你的问题,请参考以下文章

并发请求未完成时无法注销设计用户

Rails 4.2 / Devise - 如果禁用cookie,则向用户显示特定消息

Devise / Rails登录无法正常工作 - “无效的电子邮件或密码”

Rails - 如何覆盖设计SessionsController以在用户登录时执行特定任务?

Rails JSON API 的简单令牌认证注销

如何注销使用自定义设计策略登录的用户