【问题标题】:How to create "remember me checkbox" using Codeigniter session library?如何使用 Codeigniter 会话库创建“记住我的复选框”?
【发布时间】:2011-04-28 09:53:24
【问题描述】:

在 Codeigniter 中,我正在为我的网站构建一个身份验证系统,并使用会话库来实现这一目标

     session->set_userdata('username')

这将保存会话 - 我相信 - 一段时间

我想在登录表单中提供“记住我”复选框,以便用户可以永久保存会话 - 找不到永久保存会话的方法!?

注意:$sess_expiration 将不起作用,因为它为所有用户设置到期日期,而我想要做的是根据他的喜好设置到期日期

这可能吗?以及怎么做?

谢谢

【问题讨论】:

标签: php session authentication codeigniter cookies


【解决方案1】:

您可以将 sess_expiration 设置为 0,然后在会话中设置一个自定义变量,例如 remember_me=1。检查此值并在一段时间后根据需要销毁会话。 这将是一种解决方法。

【讨论】:

    【解决方案2】:

    如果记住我复选框被选中,您将在用户系统上设置一个带有随机字符串的 cookie。例如:

    $cookie = array(
        'name'   => 'remember_me_token',
        'value'  => 'Random string',
        'expire' => '1209600',  // Two weeks
        'domain' => '.your_domain.com',
        'path'   => '/'
    );
    
    set_cookie($cookie);
    

    您还可以将此随机字符串保存在 users 表中,例如在remember_me_token 列中。

    现在,当用户(尚未登录)尝试访问需要身份验证的页面时:

    • 你检查他的系统上是否有一个名为remember_me令牌的cookie
    • 如果存在,则检查数据库是否存在具有相同值的记录
    • 如果是这样,您重新创建此用户的会话(这意味着他们已登录)
    • 显示他们正在访问的页面

    如果不满足上述要求之一,则将其重定向到登录页面。

    出于安全原因,您可能希望在每次用户登录时更新随机的remember_me_token。您还可以在每次用户登录时更新 cookie 的到期日期。这样他将保持登录状态。

    为您编写所有代码的工作量太大,但我希望这有助于您自己实现此功能。如果您有任何问题,请发表评论。祝你好运。

    【讨论】:

    • 非常好的和安全的答案。荣誉
    • 'expire' =>1209600 应该是 'expire' => time() + 1209600。
    • @Priyanga,不应该。来自user guide:“过期时间以秒为单位,将添加到当前时间。”
    • @Priyanga,我猜你使用的是 PHP 的 setcookie 而不是 CodeIgniter 的 set_cookie
    • 这种方法存在一个问题,如果用户使用 2 台设备(或浏览器),则每次登录时令牌都会更改,从而使其他设备无效。您必须使用另一个表来记录每个用户的所有有效自动登录令牌,并且无法知道应该转储哪些令牌。
    【解决方案3】:

    我需要同样的东西。您无法使用 CI 设置完成此操作,因此我选择覆盖 CI Session 类(在 MY_Session 中)的 setcookie 方法:

    function _set_cookie($cookie_data = NULL)
    {
        if (is_null($cookie_data))
        {
            $cookie_data = $this->userdata;
        }
    
        // Serialize the userdata for the cookie
        $cookie_data = $this->_serialize($cookie_data);
    
        if ($this->sess_encrypt_cookie == TRUE)
        {
            $cookie_data = $this->CI->encrypt->encode($cookie_data);
        }
        else
        {
            // if encryption is not used, we provide an md5 hash to prevent userside tampering
            $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key);
        }
    
        setcookie(
                    $this->sess_cookie_name,
                    $cookie_data,
                    $this->userdata('rememberme') == true ? $this->sess_expiration + time() : 0,
                    $this->cookie_path,
                    $this->cookie_domain,
                    0
                );
    
    }
    

    当然,您需要根据用户所做的选择在会话中设置 rememberme 标志。

    【讨论】:

    • 再次如下:如果您使用数据库会话,则不能使用此解决方案,因为垃圾收集器使用 sess_expiration 清理会话表。因此,未选择“记住我”的用户将导致删除所有(按照他的标准)过期会话。
    【解决方案4】:
    $this->session->sess_expiration = '14400';    // expires in 4 hours
    $this->session->set_userdata($data);          // set session
    

    【讨论】:

    • 如果你使用这种方法,你必须在每次重新加载页面时设置sess_expiration,否则你必须在使用 set_userdata() 甚至 set_flashdata() 的任何地方显式设置它。这是因为 cookie 将被您在配置中设置的内容覆盖。
    • 如果您使用数据库会话,则不能使用此解决方案,因为垃圾收集器使用 sess_expiration 来清理会话表。因此,未选择“记住我”的用户将导致删除所有(按照他的标准)过期会话。
    【解决方案5】:

    您可以使用 isset 来检查 cookie 是否有值,如果 cookie 被删除,它将返回负数。如果是否定的,你可以重新设置cookie……当然,这就像“更新”cookie一样,所以如果用户在到期前没有来,他们就会被遗忘。 (设置一个非常大的时间直到到期!)

    例如:

    <?php
         if (isset($_COOKIE['autologin'])) {   //Checks for cookie
             echo "Welcome back!... Logging you in.";
         }else{  //Sets a cookie
             echo "Please sign in";
             $expiretime=time()+60*60*24*365; //set expire time to a year
             setcookie("autologin", "What is here is not important.", $expiretime);
         };
    ?>
    

    【讨论】:

      【解决方案6】:

      我用钩子来做这个

      1. 在“config.php”设置中启用挂钩$config['enable_hooks'] = TRUE;

      2. 在您的登录控制器中保存会话中的复选框值

        $this->session->set_userdata('remember_me', $this->input->post('remember_me'));
        
      3. 在你的“hooks.php”文件添加这个

        $hook['post_controller_constructor'] = array(
            'class'     => 'Change_Config',
            'function'  => 'change_session_expiration',
            'filename'  => 'change_config.php',
            'filepath'  => 'hooks'
        );
        
      4. 在你的“钩子”文件夹中创建一个名为“change_config.php”的文件并粘贴它

        <?php
        class Change_Config {
            public function change_session_expiration() {
                $ci = & get_instance();
        
                $remember = $ci->session->userdata('remember_me');
        
                if($remember && $ci->session->sess_expire_on_close) {
                    $new_expiration = (60*60*24*365); //A year milliseconds
        
                    $ci->config->set_item('sess_expiration', $new_expiration);
                    $ci->config->set_item('sess_expire_on_close', FALSE);
        
                    $ci->session->sess_expiration = $new_expiration;
                    $ci->session->sess_expire_on_close = FALSE;
                }
            }
        }
        

      【讨论】:

      • 那么如何查看remember_me是否过期?
      【解决方案7】:

      你可以放这个

      if ($remember) {
      
        $new_expiration = (60*60*24*365);
      
        $this->config->set_item('sess_expiration', $new_expiration);
      
        $this->config->set_item('sess_expire_on_close', FALSE);
      
        $this->session->sess_expiration = $new_expiration;
      
        $this->session->sess_expire_on_close = FALSE;
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-04
        • 1970-01-01
        • 2014-02-04
        • 1970-01-01
        相关资源
        最近更新 更多