Jump to content

Recommended Posts

Basically thought I got this working before and now i'm stuck.

I'm setting and getting a cookie using a set function ("setRememberMeToken") and retrieving them using a get function ("getRememberMeCheck") [see functions bellow in the final box]... however when i close the browser the cookie session is lost when i reopen.. I used a browser extension called Cookie-editor in chrome to check and I see nothing saved upon reopening (cookie named "token" as it uses tokens in MYSQL DB).

This is the thing, if i run (this code bellow).. it actually saves the session fine and works great... saved in a experimental file I named ~/test/test/cookithing.php.

<?php
   include '../includes/config.php';
function setRememberMeToken($pdo, $user_id) {
    $token = bin2hex(random_bytes('25'));

    $expirationDate = time() + (86400 * 7); // <-- 7 days later
    setcookie("token", $token, $expirationDate, "/");
    echo $_COOKIE["token"] = $token;
    $test = true;

    $to = date('Y-m-d', $expirationDate);

    $sql = "INSERT INTO `user_token` (`user_id`, `expires`, `tokenHash`) VALUES (?, ?, ?);";
    $stmt= $pdo->prepare($sql);
    $stmt->execute([$user_id, $to, sha1($token)]);
}
setRememberMeToken($pdo, 1);
echo "<br>";
echo sha1($_COOKIE["token"]);
?>

So by vising this page it works!.. however not ideal situation to be in as I need it to get to work upon login...

          

Forgetting about the code above for s second, here is the code I use for login (ask if you need more)...

              if (isset($_POST['remember-me'])){
                setRememberMeToken($pdo, $_SESSION["userID"] ); // <----- set token
                //echo "<br>";
                //echo sha1($_COOKIE["token"]);
              }

and the main functions are here:..

<?php
function setRememberMeToken($pdo, $user_id) {
    $token = bin2hex(random_bytes('25'));

    $expirationDate = time() + (86400 * 7); // <-- 7 days later (make sure your comments are accurate)
    setcookie("token", $token, $expirationDate, "/");
    $_COOKIE["token"] = $token;
    $test = true;

    $to = date('Y-m-d', $expirationDate);

    $sql = "INSERT INTO `user_token` (`user_id`, `expires`, `tokenHash`) VALUES (?, ?, ?);";
    $stmt= $pdo->prepare($sql);
    $stmt->execute([$user_id, $to, sha1($token)]);
}


function getRememberMeCheck($pdo) {
    $stmt = $pdo->prepare("
    SELECT users.name, users.user_id
    FROM user_token, users 
    WHERE 
        tokenHash = ? 
        AND expires > NOW()
        AND users.user_id = user_token.user_id
    ");
    $stmt->execute([sha1($_COOKIE["token"])]); 
    $db_query = $stmt->fetch();
    

    if (!$db_query){
        return false;
    }


    $_SESSION["loggedin"] = true;
    $_SESSION["username"] = $db_query['name'];
    $_SESSION["the_usr_id"] = $db_query['user_id'];
    $_SESSION["userID"]  = $db_query['user_id']; // ADDED DUE TO DESCRIPTION ("PROB WILL BE OK")
    return true;
}



function isRemembered() {

    return isset($_COOKIE['token']);
}
?>

 

Can anyone see what I'm doing wrong.. right now I'm fairly clueless..? :wtf:

 

 

 

____________

Edit: also, my header file contains this (see bellow) also.. 

     include 'includes/remember_token.php';
     include 'includes/count_online.php';
     if (isset($_COOKIE['token'])) { getRememberMeCheck($pdo); }

.. this checks if the cookie is set. 

Edited by oz11
correction

What is this line of code supposed to do for you?

echo $_COOKIE["token"] = $token;

1 - AFAIK a cookie is not available until your page is refreshed.

2 - you are making an assignment into the cookie array which would wipe out what your setcookie call just did.

Well..

    setcookie("token", $token, $expirationDate, "/");
    echo $_COOKIE["token"] = $token;

I placed it there, which was a hack, because this stops it needing/requiring a subsequent page refresh (read it on stack overflow a while ago). Anyway, that code works fine, just saying, as it works using that test file (~/test/test/cookithing.php.).. its the other bits that wont. :shrug:

I've tried adding an output to test the cookie on the main (index) page, for testing...

Even when logged in it still shows as false..

if (isset($_COOKIE["token"])){
    echo $_COOKIE["token"];
} else {
    echo "false";
}

IDK what's going wrong.

Edited by oz11
spelling
<?php
// https://forums.phpfreaks.com/topic/315262-php-cookies-and-session-data-expiring-at-different-times/
function setRememberMeToken($pdo, $user_id) {
    //$length wasn't a great name and is an unnecessary variable.
    $token = bin2hex(random_bytes('25'));

    $expirationDate = time() + (86400 * 7); // <-- 7 days later (make sure your comments are accurate)
    setcookie("token", $token, $expirationDate, "/");
    //$_COOKIE["token"] = $token;
    $test = true;

    //$_COOKIE['remember'] is unnecessary, just get rid of it
    //--deleted

    //You calculated your expiration timestamp above already, no need to do it again.
    $to = date('Y-m-d', $expirationDate);

    //Assuming token_id is an auto increment column, you can just omit it from the insert.
    $sql = "INSERT INTO `user_token` (`user_id`, `expires`, `tokenHash`) VALUES (?, ?, ?);";
    $stmt= $pdo->prepare($sql);
    $stmt->execute([$user_id, $to, sha1($token)]);
    echo "test";
}


function getRememberMeCheck($pdo) {
    //I find spacing out your queries makes them easier to read and understand.
    $stmt = $pdo->prepare("
    SELECT users.name, users.user_id
    FROM user_token, users 
    WHERE 
        tokenHash = ? 
        AND expires > NOW()
        AND users.user_id = user_token.user_id
    ");
    $stmt->execute([sha1($_COOKIE["token"])]); 
    $db_query = $stmt->fetch();
    
    //Your token and expiration date are validated as part of the query
    //All you need to do is check if you got a result or not.
    if (!$db_query){
        //If you didn't get a result, either the token is invalid or it has expired.
        //header("location: login.php");
        return false;
    }


    //Otherwise, if you did get a result, the token is valid.
    $_SESSION["loggedin"] = true;
    $_SESSION["username"] = $db_query['name'];
    $_SESSION["the_usr_id"] = $db_query['user_id'];
    $_SESSION["userID"]  = $db_query['user_id']; // ADDED DUE TO DESCRIPTION ("PROB WILL BE OK")
    return true;
}



//This method seems to just be a copy of the method above, why does it exist?
//The only difference is $_SESSION["loggedin"] = true; which you could just do above.
//function setSessionVarables($pdo) {
//...
//}
//--deleted


function isRemembered() {
    //Instead of a separate remember cookie, just check if the token cookie exists.
    //if ($whatever){ return true; } else { return false} can be simplified to just return $whatever
    return isset($_COOKIE['token']);
}
?>

- Ginerjm, is this you mean?

I want the cookie to be set so that the user is remembered once the browser is reopened. Currently it does not. The cookie vanished when I restart. 

I use the code 

Quote

     if (isset($_COOKIE['token'])) { getRememberMeCheck($pdo); }

(header.php)

.. at the top of each header to include the functions. 

and the code..

Quote

setRememberMeToken($pdo, $user['user_id']);

.. is run when the user logs in..

the function points to .. ( "  include 'includes/remember_token.php';  ")

<?php
// https://forums.phpfreaks.com/topic/315262-php-cookies-and-session-data-expiring-at-different-times/
function setRememberMeToken($pdo, $user_id) {
    //$length wasn't a great name and is an unnecessary variable.
    $token = bin2hex(random_bytes('25'));

    $expirationDate = time() + (86400 * 7); // <-- 7 days later (make sure your comments are accurate)
    setcookie("token", $token, $expirationDate, "/");
    //$_COOKIE["token"] = $token;
    $test = true;

    //$_COOKIE['remember'] is unnecessary, just get rid of it
    //--deleted

    //You calculated your expiration timestamp above already, no need to do it again.
    $to = date('Y-m-d', $expirationDate);

    //Assuming token_id is an auto increment column, you can just omit it from the insert.
    $sql = "INSERT INTO `user_token` (`user_id`, `expires`, `tokenHash`) VALUES (?, ?, ?);";
    $stmt= $pdo->prepare($sql);
    $stmt->execute([$user_id, $to, sha1($token)]);
    echo "test";
}


function getRememberMeCheck($pdo) {
    //I find spacing out your queries makes them easier to read and understand.
    $stmt = $pdo->prepare("
    SELECT users.name, users.user_id
    FROM user_token, users 
    WHERE 
        tokenHash = ? 
        AND expires > NOW()
        AND users.user_id = user_token.user_id
    ");
    $stmt->execute([sha1($_COOKIE["token"])]); 
    $db_query = $stmt->fetch();
    
    //Your token and expiration date are validated as part of the query
    //All you need to do is check if you got a result or not.
    if (!$db_query){
        //If you didn't get a result, either the token is invalid or it has expired.
        //header("location: login.php");
        return false;
    }


    //Otherwise, if you did get a result, the token is valid.
    $_SESSION["loggedin"] = true;
    $_SESSION["username"] = $db_query['name'];
    $_SESSION["the_usr_id"] = $db_query['user_id'];
    $_SESSION["userID"]  = $db_query['user_id']; // ADDED DUE TO DESCRIPTION ("PROB WILL BE OK")
    return true;
}



//This method seems to just be a copy of the method above, why does it exist?
//The only difference is $_SESSION["loggedin"] = true; which you could just do above.
//function setSessionVarables($pdo) {
//...
//}
//--deleted


function isRemembered() {
    //Instead of a separate remember cookie, just check if the token cookie exists.
    //if ($whatever){ return true; } else { return false} can be simplified to just return $whatever
    return isset($_COOKIE['token']);
}
?>

.. which contains all the necessary functions. Though these do not work for some reason, no cookies is preserved...

, help me.

 

PS: the getRememberMeCheck should preserve cookies to sessions.

Edited by oz11
addition

Oh, and the unusual thing, which i'll mention again because i think it's important is that if i run this code it  gives me a cookie (aka "token") which preserves when i restart browser..

<?php
   include '../includes/config.php';
function setRememberMeToken($pdo, $user_id) {
    //$length wasn't a great name and is an unnecessary variable.
    $token = bin2hex(random_bytes('25'));

    $expirationDate = time() + (86400 * 7); // <-- 7 days later (make sure your comments are accurate)
    setcookie("token", $token, $expirationDate, "/");
    echo $_COOKIE["token"] = $token;
    $test = true;

    //$_COOKIE['remember'] is unnecessary, just get rid of it
    //--deleted

    //You calculated your expiration timestamp above already, no need to do it again.
    $to = date('Y-m-d', $expirationDate);

    //Assuming token_id is an auto increment column, you can just omit it from the insert.
    $sql = "INSERT INTO `user_token` (`user_id`, `expires`, `tokenHash`) VALUES (?, ?, ?);";
    $stmt= $pdo->prepare($sql);
    $stmt->execute([$user_id, $to, sha1($token)]);
}
setRememberMeToken($pdo, 1);
echo "<br>";

?>

But cannot get it to work in the login.. could someone help or give me a write up/ suggestion. :)

Edit: this is run in a separate experimental file and seems make things work-ish.

Also, the $user_id is set to "1" for testing, normally this will be a value selected from the DB!

 

Though: 

  • cannot get it to work by placing the code directly in the login system
  • etc.
Edited by oz11

Don't understand but I have to ask.  How do you know the cookie was actually set?  Have you looked up the function in the PHP manual to see that you are using it properly?  I don't see where your code verifies that it was set.

I actually use the code 

if (isset($_COOKIE['token'])){
    echo $_COOKIE['token'];
} else {
    echo "flase";
}

as well as a browser extension called Cookie-editor in chromium. 

PS: The code ^ i place in one of the files which include the functions, if you understand. 

Edited by oz11
20 minutes ago, ginerjm said:

If you looked at the Official PHP Manual you would get the true way to use it.   W3schools?  Nah...

You should be using:

if (setcookie(.......))

ok

else

   not ok

Ah. that's neat.  Also, could you point me to any code which says this is the best method, I cannot see it used in the manual for "setcookie" :confused:

 

But getting a false now even when set ,... and i don't think it has to do with the cookie not being present.

if (setcookie('token')){
    echo $_COOKIE['token'];
} else {
    echo "false";
}

 

Edited by oz11

Anyway.. minus the little dependencies...  the code run from login.php displays a "false" (not set) while running it from the ~/test/test/cookithing.php file i get the output of the cookie (set). :wtf:

1 minute ago, ginerjm said:

That code is totally incorrect.   Use the setcookie statement that you had, just wrap it in the if statement.

I'm not quite sure where you mean.. could you writeup for me?

Here is the manual's intro page:

setcookie
(PHP 4, PHP 5, PHP 7, PHP 8)

setcookie — Send a cookie

Description ¶
setcookie(
    string $name,
    string $value = "",
    int $expires_or_options = 0,
    string $path = "",
    string $domain = "",
    bool $secure = false,
    bool $httponly = false
): bool

See how the definition of the function includes the output at the end showing it is giving you a boolean result?

Huh?   What looks "optional" to you?  You don't see what as being necessary?  You may not need all those settings but if you at least write the statement so that you can get a result from it you may find out something.

Just try what I recommended

if (!setcookie("token", $token, $expirationDate, "/"))
{
	echo "Could not set cookie for $token using $expirationDate - aborting";
	exit();
}
 

 

If you don't want to work with me I guess we are done.  I'm giving ou some coding tips in order to debug your problem and you don't want to try it because you "see" something.  I thought the issue was the cookie wasn't being set and I wanted PHP to tell me that, but you don't want to follow my lead.

oh well.....

Edited by ginerjm

It's not that. I genuinely didn't get the code. 99% of people use an "isset". 

 

Anyway, i digested the code finally and have some output which might be interesting...
Basically, the login page returned this .. ( ignore some of the extra "testing" strings :p ). So this is true/unsuccessful 

1174611373_Screenshotfrom2022-12-1616-54-43.png.e656ed2f88d2840de14e5a662f739208.png

And the test file was a white page (successful/"false") 

 

:)

 

 

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.