【问题标题】:Destroying a specific session in Code Igniter销毁 Codeigniter 中的特定会话
【发布时间】:2012-03-22 17:59:10
【问题描述】:

我希望能够让用户退出我在 Code Igniter 中构建的应用。

我知道如何结束活动的本地会话:

$this->session->sess_destroy();

但是我怎样才能销毁在另一台计算机上启动的会话,从而使用户退出他们的会话?

我在会话数据中存储了与他们的帐户关联的唯一 ID,因此我可以在数据库的会话表中看到它,但它与其他会话数据一起存储在名为 user_data 的列中,其中的内容看起来像这样:

a:4:
{s:9:"user_data";s:0:"";s:6:"userid";s:6:"189034";s:9:"logged_in";b:1;s:5:"token";i:1767727789;}

189034 是用户 ID。

那么,有没有办法以某种方式根据用户的 id 在会话表中选择行,然后删除该行并销毁会话。还是有其他方法可以完全做到这一点?

【问题讨论】:

    标签: codeigniter session destroy


    【解决方案1】:

    在 ci_session 表中创建一个新列。

    ALTER TABLE `yourdatabase`.`ci_sessions` 
    ADD COLUMN `userid` VARCHAR(45) NULL  AFTER `user_data` ;
    

    然后在您的登录函数中从您的登录过程中获取 id,然后在将用户数据信息添加到会话之前执行以下操作:

    /* Delete any existing sessions with the current userid session.
    Note - a new session has already been generated but doesn't have a value
    in the userid column, so won't get deleted. */
    $this->db->delete('ci_sessions',array('userid' => $identity));    
    
    // Get the current session and update it with the userid value.
    $session_id = $this->session->userdata('session_id');
    $this->db->where('session_id', $session_id);
    $this->db->update('ci_sessions', array('userid' => $identity));
    

    $identity 是您的用户 ID。这会清除之前的所有会话,意味着一次只存在一个。

    【讨论】:

    • 在重新生成会话 ID 时,您不会丢失 userid 值吗?我以为这就是我们在 cmets 中讨论的问题?
    • 没有。当用户从第二台机器登录但在用户通过身份验证之前创建一个新会话,因此此时数据库中有两条记录。使用上面的代码,旧的会话记录被破坏,新的会话记录简单地更新会话信息。我已经将答案编辑得更清楚了。
    • 我的意思是当同一个会话regenerates it's own id"...the session class will check to see if valid session data exists in the user's session cookie...If a session does exist, its information will be updated ... With each update, the session_id will be regenerated."我忽略了什么?
    • 那里的关键词是“更新”。数据库表中的元组(记录)是更新的,而不是删除和插入的。即 codeigniter 运行的 SQL 代码是 'update ci_sessions set session_id = '456def' 其中 session_id = 'abc123'。因此,只要会话存在,就保持 userid 列的完整性。
    • 如果您使用 C3,这应该是查询: ALTER TABLE yourdatabase.ci_sessions ADD COLUMN userid VARCHAR(45) NULL AFTER data ;
    【解决方案2】:

    有销毁你想要的一些项目/会话的功能

    $this->session->unset_userdata('session_name')
    

    并允许一个用户一次登录一台计算机或一次登录一个浏览器,您可以在此处阅读更多信息

    Allow one session only at a time

    【讨论】:

      【解决方案3】:

      序列化数据的一个问题是没有合法的方法来查询它。您必须获取会话中的所有用户(可能是很多)并解压缩数据,检查值,然后删除会话表中的行,从而有效地破坏该会话。

      foreach ($this->db->get('sessions')->result() as $session)
      {
          $data = unserialize($session->user_data);
      
          if ( ! isset($data['user_id'])) continue;
      
          if ($data['user_id'] === $id_to_delete)
          {
              // delete the row
                  $this->db->where('session_id', $session->session_id)
                      ->delete('sessions');
          }
      }
      

      我可能不鼓励这样做。您网站上的每个用户,无论是否登录,都有一个必须被挑选出来的会话,请记住:一个用户可能有多个会话,因此您必须循环浏览每一个。

      另一种方法是使用用户 ID(或 ID 的哈希)向会话表添加自定义列。您可以查询以快速找到用户会话的东西。然后,当您将 user_id 添加到 session 时,填充此列,当您需要通过 user_id 删除 session 时,可以快速高效地完成。

      【讨论】:

      • 我也反对这种方法。你的第二个建议更现实。
      • 虽然只添加这个功能是最简单的,但如果你有很大的会话表,这并不是最好的。
      • 我不鼓励大家一起做这个项目,因为它会导致死胡同,没有出路,但我认为这个建议有点太晚了。所有最好的兄弟!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-23
      相关资源
      最近更新 更多