oz11 Posted December 16, 2022 Share Posted December 16, 2022 (edited) 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..? ____________ 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 December 16, 2022 by oz11 correction Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 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. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 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. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) 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 December 16, 2022 by oz11 spelling Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 Show us the updated code that you first posted Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 <?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? Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 So - now what is the error you are getting or exactly what is not working? I don't see any use of the cookie you set. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) 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 December 16, 2022 by oz11 addition Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) 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 December 16, 2022 by oz11 Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 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. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) 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 December 16, 2022 by oz11 Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 The proper way to test is to evaluate the result of the call like it shows in the manual. It is a boolean function Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) IDK man. Looks ok to me https://www.w3schools.com/php/func_network_setcookie.asp I don't understand.. Where do I need a boolean here? Edited December 16, 2022 by oz11 Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 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 Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) 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" 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 December 16, 2022 by oz11 Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 That code is totally incorrect. Use the setcookie statement that you had, just wrap it in the if statement. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 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). Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 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? Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 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? Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 And no I cannot write it up for you if you don't understand what I'm telling you. Thought you knew how to code but apparently you don't. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 I don understand. I didn't see it being necessary. Just need a cookie holding a string (token for login), they look optional to me (bool) Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 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(); } Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) I can tell by my menu bar or extension that the cookies are set or not.. do you see any other problems other than the syntax of the cookie check?? Edited December 16, 2022 by oz11 Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 (edited) 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 December 16, 2022 by ginerjm Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 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 And the test file was a white page (successful/"false") Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.