How to create "remember me checkbox" using Codeigniter session library?

44,445

Solution 1

If the remember me checkbox is checked you set a cookie on the user's system with a random string. E.g.:

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

set_cookie($cookie);

You also save this random string in the users table, e.g. in the column remember_me_token.

Now, when a user (who is not yet logged in) tries to access a page that requires authentication:

  • you check if there is a cookie by the name of remember_me token on his system
  • if it's there, you check the database if there is a record with the same value
  • if so, you recreate this user's session (this means they are logged in)
  • show the page they were visiting

If one of the requirements above is not met, you redirect them to the login page.

For security reasons you may want to renew the random remember_me_token every time the user logs in. You can also update the expiry date of the cookie every time the user logs in. This way he will stay logged in.

It would be too much work to write all the code for you, but I hope this helps you to implement this functionality yourself. Please comment if you have any questions. Good luck.

Solution 2

I needed the same thing. You cannot accomplish this using CI settings so I have chosen to override the setcookie method of the CI Session class (in MY_Session):

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
            );

}

Of course you need to set the rememberme flag in your session based upon the choice the user made.

Solution 3

I used hooks to do this

  1. Enable hooks in "config.php" setting $config['enable_hooks'] = TRUE;

  2. In your login controller save the checkbox value on session

    $this->session->set_userdata('remember_me', $this->input->post('remember_me'));
    
  3. In your "hooks.php" file add this

    $hook['post_controller_constructor'] = array(
        'class'     => 'Change_Config',
        'function'  => 'change_session_expiration',
        'filename'  => 'change_config.php',
        'filepath'  => 'hooks'
    );
    
  4. In your "hooks" folder create a file called "change_config.php" and paste this

    <?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;
            }
        }
    }
    

Solution 4

You could use isset to check if the cookie has a value, and if the cookie is deleted, it will return negative. If it is negative, you can set the cookie again... of course, this will be like "renewing" the cookie, so if the user doesn't come by the expiration, they will be forgotten. (Set a very big time till the expiration!)

For example:

<?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);
     };
?>

Solution 5

$this->session->sess_expiration = '14400';    // expires in 4 hours
$this->session->set_userdata($data);          // set session
Share:
44,445

Related videos on Youtube

ahmed
Author by

ahmed

Updated on July 09, 2022

Comments

  • ahmed
    ahmed almost 2 years

    in Codeigniter I am building an Authentication system for my web site and to achieve that I use session library

         session->set_userdata('username')
    

    this will save the session -I believe- for some time

    I want to provide a "remember me" checkbox in the login form so the user can save the session forever - could not find a way to save the session forever!?

    Note:$sess_expiration will not work because it sets expiration date for all users and what I want to do is setting the expiration date based on his preferences

    is that possible? and how to do it?

    Thanks

  • seedg
    seedg almost 12 years
    Very nice and secure answer. Kudos
  • Namal
    Namal about 11 years
    'expire' =>1209600 should be as 'expire' => time() + 1209600.
  • Mischa
    Mischa about 11 years
    @Priyanga, no it shouldn't. From the user guide: "The expiration is set in seconds, which will be added to the current time."
  • Namal
    Namal about 11 years
    @Mischa But it doesn't work when I add only 1209600. I had to add time()+ too.
  • Mischa
    Mischa almost 11 years
    @Priyanga, I guess you're using PHP's setcookie instead of CodeIgniter's set_cookie then.
  • SlimDeluxe
    SlimDeluxe about 10 years
    There's a problem with this approach, if the user is using 2 devices (or browsers) the token will change with each login, thus invalidating the other device. You'd have to use another table to note all the valid auto-login tokens for each user and there's no way to know which tokens should be dumped.
  • SlimDeluxe
    SlimDeluxe about 10 years
    If you use this approach, you have to set sess_expiration on each page reload, else you have to explicitly set it anywhere where you use set_userdata() or even set_flashdata(). This is because the cookie will be overwritten with what you have set in the config.
  • SlimDeluxe
    SlimDeluxe about 10 years
    If you are using database sessions, you can't use this solution, because the garbage collector uses the sess_expiration to clean the sessions table. So a user who has not chosen "remember me", will cause the deletion of all (by his standards) expired sessions.
  • SlimDeluxe
    SlimDeluxe about 10 years
    Again as below: If you are using database sessions, you can't use this solution, because the garbage collector uses the sess_expiration to clean the sessions table. So a user who has not chosen "remember me", will cause the deletion of all (by his standards) expired sessions.
  • Mischa
    Mischa about 10 years
    @OmerSabic, good point. You could add a token_last_used_at column to the extra table you're mentioning and periodically dump the tokens that haven't been used for a while.
  • rahul
    rahul almost 5 years
    Then how to check whether remember_me has expired or not ?