ginerjm Posted December 16, 2022 Share Posted December 16, 2022 (edited) Could I see that GD code? AND - I am trying to verify that the setcookie runs ok and not looking for something being set. There's a big difference between the two things. When working with someone on one's code changes it usually works better if you POST the new code so that we can agree on what we've done. Not show me some garbage from something else. 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 <?php include '../includes/config.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, "/"); 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)]); if (!setcookie("token", $token, $expirationDate, "/")) { echo "Could not set cookie for $token using $expirationDate - aborting"; exit(); } } setRememberMeToken($pdo, 1); echo "<br>"; ?> [test file] && <?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----------------"; if (!setcookie("token", $token, $expirationDate, "/")) { echo "Could not set cookie for $token using $expirationDate - aborting"; exit(); } } 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']); } ?> [functions] Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 Where is the code you modified to do as I asked????? That is what I wanted to see. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) That is the modified code . See.. if (!setcookie("token", $token, $expirationDate, "/")) { echo "Could not set cookie for $token using $expirationDate - aborting"; exit(); } it's inserted in both files. The test file #1 and also placed in the functions file (#2), for testing purposes as i thought you wanted..? 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 It should only be in the ONE script that we are working to fix. I don't need the confusion of you dealing with 2 scripts. And what happened when you ran this code? In fact add this to the above: else echo "Setcookie ran ok"; Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 ah ok.. I'll just post this .. Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 Ok - after 4 hours we finally found out that your setcookie statement is NOT setting the cookie. I think you may need to add some more of the parms that the manual showed you. Never mind. I'm going to shovel snow and may not be back. Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted December 16, 2022 Share Posted December 16, 2022 do you have php's error_reporting set to E_ALL and display_errors set to ON, preferably in the php.ini on your system, so that php would help you by telling you why the setcookie() call is failing? Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) Both set but no errors when "logging in" aka "setRememberMeToken"... [whole functions] <?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, "/"); setcookie("token", $token, time() + (86400 * 30)); // 86400 = 1 day $_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----------------"; if (!setcookie("token", $token, $expirationDate)) { echo "Could not set cookie for $token using $expirationDate - aborting"; exit(); } else { echo "Setcookie ran ok"; } } 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']); } ?> Sorry Ginerjm, just having been doing it that long (PHP). 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 We ARE not worried about 'logging in'. We are worried about ANY error that may be happening. I gave you the code to turn on error reporting. Did you put it at the top of the script right after you ran your session_start? Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) Sorry about the late reply, i have just spent ages solving the other error messages dotted all over my site and had a mental health issue before .. but feeling good and stable now. Like i suggested i added this config... Quote error_reporting(E_ALL); ini_set('display_errors', '1'); and got these results which i think are relative .. Current code [remember_token.php]: <?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)]); //echo "test----------------"; if (!setcookie('token', $token, $expirationDate, "/")) { echo "Could not set cookie for $token using $expirationDate - aborting"; // exit(); } else { echo "Setcookie ran ok"; } if (isset($_COOKIE['tip3'])) echo "<br>good cookie"; if (isset($_COOKIE['token'])) echo "<br>good cookie2"; } 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']); } ?> Current code [login.php]: <?php $the_page = " - Login/ Register"; session_start(); include 'includes/top_bottom/header.php'; if((isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] == true) && (isset($_SESSION["username"]))) { //header('Location: dash.php'); } $base = basename(parse_url($_SERVER['HTTP_REFERER'],PHP_URL_PATH)); ?> <center> <?php include 'includes/logo.php'; ?><!--<img src="mark.png" alt="beta project" width="80px;" style="margin-left: -184px; margin-bottom: 150px;">--><br> <h2>Login/ register</h2> <?php if($_SERVER["REQUEST_METHOD"] == "POST"){ $username = trim($_POST["username"]); $password = trim($_POST["password"]); // Check if username is empty if(empty(trim($_POST["username"]))){ echo $username_err = "<span id='notification'>Please enter username.</span> "; } else{ $username = trim($_POST["username"]); } // Check if password is empty if(empty(trim($_POST["password"]))){ echo $password_err = "<span id='notification'>Please enter your password.</span> "; } else{ $password = trim($_POST["password"]); } // continue... if(empty($username_err) && empty($password_err)){ $sql = "SELECT user_id, name, password, active FROM users WHERE name = ?"; $result = $pdo->prepare($sql); $result->bindParam(1, $_POST["username"]); $result->execute(); $user = $result->fetch(); if(!password_verify($_POST['password'], $user['password'])){ echo "<span id='notification'>Invalid username/password.</span> "; } else { if($user['active'] == '1') { $_SESSION["loggedin"] = true; $_SESSION["username"] = $_POST["username"]; $_SESSION["userID"] = $user['user_id']; // cookie stuff if (isset($_POST['remember-me'])){ echo setRememberMeToken($pdo, $user['user_id']); // <----- set token echo "<--woo"; } echo "Hey ".$_SESSION["username"].". You are Logged in, redirecting in a moment or click <a href='dash.php'>here</a> to be taken to your dashboard."; //header("location:loggingin.php?id=true"); include 'includes/top_bottom/footer.php'; exit(); }else { echo "User not active."; } } } } Edited December 16, 2022 by oz11 added "login.php" Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 Well we already know that setcookie as you are calling it is not working. Fill out the rest of the parms and try that AND DO IT THE WAY i TOLD YOU USING AN IF STATEMENT TO TEST THE RESULT. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) Just tried with seven parameters (max all) based on the manual.. 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, '/', 'localhost', true, true); $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)]); //echo "test----------------"; if (!setcookie("token", $token, $expirationDate, "/")) { echo "Could not set cookie for $token using $expirationDate - aborting"; // exit(); } else { echo "Setcookie ran ok"; } // if (isset($_COOKIE['tip3'])) // echo "<br>good cookie"; // if (isset($_COOKIE["token"])) // echo "<br>good cookie2"; } Still getting errors. As you can see I'm using your testing method. Edited December 16, 2022 by oz11 Quote Link to comment Share on other sites More sharing options...
kicken Posted December 16, 2022 Share Posted December 16, 2022 You cannot set a cookie after you've already sent output. Cookies are part of the headers (ie, setcookie just turns into header('Set-cookie: ...')) so they must come before any other script output. That's what those errors are telling you. You have output starting in colourmodes.php on line 32 which is preventing your cookie from being set. You need to re-structure your application so you can set your cookies before anything else happens that would cause output to be sent. Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 16, 2022 Share Posted December 16, 2022 Why do you set the cookie twice and do it differently each time? I see one of them is still telling you that it's not working but the other one you did not alter to use an if to test the result. Those error messages about output being alread sent. That could also be the error messages I'm having you output once we resolve this issue. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) Whey. Seems like something is happening... Oky doky. Cookies seem to be working now.. could I ask of another question, does anyone know what this Error message could suggest: (once I've logged in and sent to the dashboard). I've cleaned a fair few today but cannot solve this alone seemingly .. _________ ginerjm.. I'm still getting this result even when cookies have indeed been set. @ ginerjmoh... And i define the cookie twice as it stops me needing to refresh the page for the cookie to be set. A hack i got from someone on SO,. Edited December 16, 2022 by oz11 Quote Link to comment Share on other sites More sharing options...
gizmola Posted December 16, 2022 Share Posted December 16, 2022 6 hours ago, oz11 said: 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? Please don't ever use w3schools as documentation for anything related to PHP. The PHP manual is complete and well written, and also tends to have some excellent comments illustrating use or warning of gotchas. For example, the manual page says this: Quote If output exists prior to calling this function, setcookie() will fail and return false. If setcookie() successfully runs, it will return true. This does not indicate whether the user accepted the cookie. So it looks from your recent test that something has already sent the http header prior to trying to set the cookie. That won't work. Irrelevant to your problems, my advice on setting the time, as a more readable and simple solution: $expirationDate = strtotime('+7 days') // <-- 7 days later (make sure your comments are accurate) Where are you running this code during development? Are you by chance using a localhost environment? Since you aren't setting the domain in your setCookie, it is a long standing and well known issue that cookies require a valid domain, and "localhost" is not valid as it has no TLD (.something). At this point, there are 3 recommended choices for a tld configuration you would make on your workstation. (.test, .example or .dev). .test and .example are reserved in the RFC's so there is no issue adding a domain to your workstation in a "/etc/hosts" files mapping it to 127.0.0.1. .dev was purchased by Google, and is unused, so many people have decided to use that for development, and is known to work fine and have no conflicts. I personally use www.something.test for development projects, so I'll map both 'something.test' and 'www.something.test' in my /etc/hosts file. Quote Link to comment Share on other sites More sharing options...
gizmola Posted December 16, 2022 Share Posted December 16, 2022 Don't use include. Use require_once(). The fact that you are having these issues speaks to lack of structure in the code you are writing, and the high probability that using MVC with a front controller would be advisable. Quote Link to comment Share on other sites More sharing options...
oz11 Posted December 16, 2022 Author Share Posted December 16, 2022 (edited) Cleaned up the errors.. and deleted the content of coloumodes.php, changed it around abit and re placed it in the page... Worked without it so just had to fix it up. Anyway, since following the error it became clear! But with the help you you guys gizmola and ginerjm. So much thanks for your advice. PS: cant believe i didn't know about error reporting, never used it before and makes me feel more secure now. Going to sleep now, at it all day and has been like 10 hours.. lucky i can go to bed with a clear mind. Again, thanks ginerjm and gizmola Edited December 16, 2022 by oz11 Quote Link to comment Share on other sites More sharing options...
ginerjm Posted December 17, 2022 Share Posted December 17, 2022 Happy that I was able to contribute. Don't forget to turn off error checking before putting into production. Quote Link to comment Share on other sites More sharing options...
Barand Posted December 17, 2022 Share Posted December 17, 2022 9 hours ago, ginerjm said: Don't forget to turn off error checking before putting into production. Nothing can possibly go wrong in production? Just in case, leave error checking on but change from displaying the errors to logging them instead. 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.