【问题标题】:How to invalidate all sessions after user log out in Rails?用户在 Rails 中注销后如何使所有会话无效?
【发布时间】:2022-03-05 05:30:16
【问题描述】:

我是 Rails 新手,我正在关注 Michael Hartl 的 Rails 教程,所以我的代码大部分是从那里借来的。这是场景:

我使用Computer A 登录我的网站。然后我使用Computer B 使用相同的用户ID 登录该站点。当我使用Computer A 退出站点时,Computer B 仍然处于登录状态,并且仍然可以执行操作。出于安全原因,我希望Computer BComputer A 注销后强制重新登录。是否有一种简单的方法可以在注销时使给定用户的所有会话无效?如果您有一些示例代码,将不胜感激。

我还了解到,在注销时使用 reset_session 是最佳做法。但是,我无法确定您应该在注销用户之前还是之后使用reset_session

这是来自我的会话控制器:

  def destroy

    log_out if logged_in?

     # Reset session to prevent session fixation vulnerability
    reset_session

    flash[:info] = "You are now logged out"
    redirect_to root_url
  end

这是来自我的会话助手:

  # Forgets a persistent session
  def forget(user)
    user.forget
    cookies.delete(:user_id)
    cookies.delete(:remember_token)
  end

  # Logs out the current user
  def log_out
    forget(current_user)
    session.delete(:user_id)
    @current_user = nil
  end

【问题讨论】:

    标签: ruby-on-rails session-cookies


    【解决方案1】:

    这是他们必须的工作。

    会话取决于浏览器。如果登录一台 PC,那么您的会话将保留在您当前工作的同一浏览器上。如果您使用另一台 PC 登录,那么您的浏览器会为您创建另一个会话。

    您可以使用谷歌和 Facebook 等知名网站尝试此方案。

    请参考以下链接。

    What are sessions? How do they work?

    如果您尝试在单台机器上销毁所有会话,您可以尝试。

    rake db:sessions:clear
    

    【讨论】:

      【解决方案2】:

      您可以解决此问题的一种方法是在您的用户模型上设置一个标志,我们称之为activestatus,这将是您数据库中的一个布尔列。当用户注销时,您将活动列设置为false。现在,在您的 current_user 方法中,在您的控制器中,您只需要检查用户是否为 active,如果不清除会话。

      这里有一个小sn-p,我可以为此乱写:

      class User
       # you should add an active or status column through a migration
       # enum status: {true => :active, false => :inactive} # largely personal preference for enums, you could define other helper methods without needing the enums
      end
      
      # x_controller
      def log_out
        ...
        user.inactive!
        ...
      end
      
      
      def current_user
        if @current_user ||= User.active.find_by_id(session[:user_id])
         # the user is active continue
         @current_user
        else
         # the user is not active clear the session
         session.clear
        end
      end
      

      之前没有尝试过代码,但这是我认为您可以完成此操作的一种方式。

      【讨论】:

        【解决方案3】:

        根据@oreoluwa 的回答,这对我在清理 PII 后软删除帐户很有用:

        ALTER TABLE `users`
        ADD `is_deleted` TINYINT(1) NOT NULL DEFAULT '0';
        
        class ApplicationController < ActionController::Base
        
          before_action :require_login
        
          # ...
        
          def require_login
            if not logged_in?
              return redirect_to welcome_path
            end
        
            if current_user != nil and current_user.is_deleted
              session.destroy
              return redirect_to welcome_path
            end
          end
        
          # ...
        
        end
        

        【讨论】:

          猜你喜欢
          • 2015-08-14
          • 2012-01-24
          • 1970-01-01
          • 2020-05-10
          • 2012-01-21
          • 2019-07-09
          • 2016-02-17
          • 1970-01-01
          相关资源
          最近更新 更多