-3

In my code I have the option to select "Remember me", which when checked saves the values of the email and password in a cookie and the cookie lasts 1 month, now, when the user enters the page again, the session does not it stays active, but it does get the values from the saved cookie and displays it on the login form. I am currently using cloudflare and a hosting, I already tried to establish these lines of code:

php_value session.cookie_lifetime 2629800;
php_value session.gc_maxlifetime 2629800;

both in the php.ini and the .htacces but the result is the same (when the user closes the browser the session is closed).

This is the loginUser function that handles the login and creates a cookie if the user checks "Remember me" and what I want is that by checking remind me the session stays active even if the user closes the browser or comes back after some time inactivity, but that the session has a duration of 1 month (2629800s).

function loginUser($email, $password, $rememberme)
{
    $mysqli = connect();
    $email = trim($email);
    $password = trim($password);
    
    if ($email == "" || $password == "") {
        return 'Both fields are required';
    }

    $email = filter_var($email, FILTER_SANITIZE_EMAIL);
    $password = filter_var($password, FILTER_SANITIZE_SPECIAL_CHARS);
    
    $sql = "SELECT * FROM users WHERE email = ? LIMIT 1";
    $stmt = $mysqli->prepare($sql);
    $stmt->bind_param("s", $email);
    $stmt->execute();
    $result = $stmt->get_result();
    $data = $result->fetch_assoc();

    if ($data == NULL) {
        return 'The email does not exist, sign up to enter';
    }

    if (password_verify($password, $data["password"]) == FALSE) {
        return 'The password is incorrect, please check and try again';
    } else {
        $user_id = $data['user_id'];
        $_SESSION['auth_user_id'] = $user_id;
        $_SESSION["user"] = $email;
        $_SESSION["pass"] = $password;
        $_SESSION["username"] = $data['username'];
        $_SESSION["verify"] = $data['verify'];
        $_SESSION["profile"] = $data['profileImage'];
        $_SESSION["id"] = $data['user_id'];
        $_SESSION["vip"] = $data['vip'];

        setcookie('user_id', $data['user_id'], time() + 60 * 60 * 24 * 30, '/');

        if ($rememberme) {
            $cookie_name = 'Remember_US';
            $cookie_value = json_encode(array('lemail' => $email, 'lpassword' => $password));
            $cookie_expire = time() + (60 * 60 * 24 * 30);
            setcookie($cookie_name, encrypt($cookie_value), $cookie_expire, '/', null, true, true);
        }
        header("location: index.php");
        exit();
    }
}

PS: I know this is a duplicate, but none of the questions above fixed my problem.

I mention again, I tried to set these lines in the htaccess and in the php.ini and I didn't succeed:

php_value session.cookie_lifetime 2629800;
php_value session.gc_maxlifetime 2629800;

//In functions.php
$expire = 60*60*24*30; // We choose a one year duration
ini_set('session.gc_maxlifetime', $expire);
session_start();

It is also worth mentioning that by establishing the lines of code when I close the browser and reopen it, the session remains active, but it only lasts a maximum of 2 hours.

RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
Dev.Fra
  • 11
  • 2
  • 3
    Saves the password in a cookie? WHY? And you should not do that – RiggsFolly Apr 03 '23 at 16:00
  • the values are encrypted and are 100% secure according to ChatGPT. – Dev.Fra Apr 03 '23 at 16:08
  • 2
    You should not mess with passwords, dont trim them and dont filter them. They are completely up to the user to define. Its completely unnecessary anyway as you are going to HASH whatever the use enters so it cannot be a SQL Injection vector – RiggsFolly Apr 03 '23 at 16:13
  • Anyway, you dont need a password to log a user in from your backend. All you actually need is the Userid, so you can select the user data from the database and place it all in the SESSION so your app knows the user is logged in. There is no need to place the password in the SESSION either, afterall you are trying to get PHP to leave the session lying around in a file for 1 month. Thats a pretty GOOD vector for a hack (internal most likely, but most hacks require a bit of inside help remember) – RiggsFolly Apr 03 '23 at 16:17
  • You dont show us how you call this function! Are you setting `$rememberme` and if so to what? A [Minimal, Complete and Verifiable Example](http://stackoverflow.com/help/mcve) might be useful so we an test your code – RiggsFolly Apr 03 '23 at 16:30
  • @RiggsFolly while the user ID is _technically_ all that is required, isn't more info required to verify the client actually owns that user ID? – GrumpyCrouton Apr 03 '23 at 17:59
  • 2
    The terminology in your question is important. A session expires when someone closes their browser, that's the nature of that type of cookie. No changes on the server will affect this (except causing it to expire sooner). So what you are looking for is both a session cookie, as well as a fallback device to prove the user if that cookie is absent. This is a [great answer](https://security.stackexchange.com/a/109439/86698) that includes some PHP. – Chris Haas Apr 03 '23 at 18:03
  • 2
    `according to ChatGPT`...chatGPT is a tool for generating human-like conversations. It's [not a knowledge base](https://theconversation.com/chatgpt-is-great-youre-just-using-it-wrong-198848). Don't ever assume that anything it tells you is factually correct (sometimes it will be, but often it won't be). It merely takes data it found online and inserts it into the answer where it thinks it _sounds plausible_. It doesn't _know_ anything. – ADyson Apr 03 '23 at 18:36
  • @Dev.Fra Try [this code](https://git.sr.ht/~kofeigen/session-test) on your server (see installation instructions) to see if it works. You should be able to update it to do what you want. – kofeigen Apr 05 '23 at 00:37

1 Answers1

0

TL;DR The setcookie lifetime is being confused with the lifetime of the default PHPSESSID cookie for $_SESSION.

To make $_SESSION respect the desired lifetime, its PHPSESSID cookie must be updated to change the cookie_lifetime from its default to one month. This involves managing $_SESSION manually. The following is an example workflow for managing $_SESSION manually:

  1. Set the session_name. (An alternative cookie name to PHPSESSID can be set.)
  2. Configure session options. (This can include setting the cookie_lifetime.)
  3. Create and/or set the session_id.
  4. Start the session. (This step populates $_SESSION based on the session_id.)
  5. Validate the session. (Check that the session_id and other authentication parameters are valid.)
  6. Access and modify $_SESSION values.
  7. Close the session. (Block $_SESSION from further changes before sending the session_id to the client.)

This link on Session Management Basics should be helpful. You could also read about PHP Session Fixation / Hijacking.

In the comments RiggsFolly offers advice to think about, and Chris Haas posted a good reference. Solutions like the reference seem to suggest storing a random string as a user lookup key, and a longer, hashed string for validation. The lookup and non-hashed validation string would use setcookie, while other values could use $_SESSION.

kofeigen
  • 1,331
  • 4
  • 8