0

When a user loads a page, I want to test whether they have gone from the login page OR have a cookie on their PC saying that they have logged in previously, however it seems the latter doesn't work.

if ($pass === $PassConfirm || $_COOKIE['loggedIn'] == "true"){
 //Set cookie for logging in, (86400/24) lasts 1 hour
 setcookie("loggedIn", "true", time() + (86400 / 24), "/");
 /* Code to do stuff */
}else{
echo 'You are not logged in';}

This is what I am using to test they have just logged in OR have the cookie. If I enter the page from the login page, with the correct password, it loads just fine. However, when checking that the value of the cookie is "true" (which it gets set as, and I can see is set when I look at my cookies for the page in Chrome) it errors saying I am not logged in.

Jordan
  • 61
  • 1
  • 14
  • I am saying that I can easily fool your script by setting cookie by hand – Marcin Orlowski May 11 '16 at 15:57
  • Don't worry, the cookie isn't going to be that, it is just something simple to test it works – Jordan May 11 '16 at 15:57
  • anyway, you should test the right way. Use session – Marcin Orlowski May 11 '16 at 15:58
  • 1
    Don't use cookies as they are easily manipulated instead use `$_SESSION['session'];` , For more take a look at : http://php.net/manual/en/reserved.variables.session.php – Umair Shah May 11 '16 at 15:59
  • And why are you setting `loggedIn` Cookie again upon checking that if it is already set??? – Umair Shah May 11 '16 at 16:01
  • @UmairShahYousafzai It's being set if the password is put in, but the cookie isn't. – Jordan May 11 '16 at 16:03
  • @Jordan : But you know that you are using `||` which means `OR` if any of the conditions are true so it will execute the code..! what if your first conditions fails and the 2nd is true so then??? – Umair Shah May 11 '16 at 16:05
  • @UmairShahYousafzai that's how it should be. If they logged in with a password OR if they have the cookie/session set to true – Jordan May 11 '16 at 16:06

1 Answers1

1

Your code structure needs some heavy refining, if you insist on using cookies, so be it, but it is recommended (in comments and by others) to use $_SESSION instead of cookies (as their data contents are stored more securely and use cookies to communicate with the end user in the same way).

Reform your code to now do:

if (password match){
    //password check 
}
elseif (cookie match){
    //cookie check
}else {
    //unauthorised. (You should redirect).
}

So

if (password_verify($pass, $PassConfirm)){
   /***
    Password is matched with the hash so now set the cookie
   ***/
   //set cookie - I will say more about this further down...
   setcookie("loggedIn", "true", time() + (86400 / 24), "/");
}
elseif ($_COOKIE['loggedIn'] == "true") {
   /***
   Cookie data found so assumed correct. carry on.
    ***/
}
else{
    echo 'You are not logged in';
    /***
    Some form of error handling. Typcially a header() statement and page redirection
    ***/
    header("Location: index.php");
    exit;
}
// Now your "rest of code" activity can begin here safe in the 
// knowledege that only people with passwords or cookies will reach this part.
  • Please read up about PHP Password Verify and the corresponding Password_hash functions.

  • Your cookie checks can and will be manipulated, make an improvement by using SESSIONS, which also handle lifetimes and logging in and out much easier as well.

  • for failed states such as the else statement you should ideally not stay on the same page and redirect the user to another page via an intermediary page which will clear the cookie/session data and "clean" their associated data.

  • Please read the notes from the manual for setcookies, including:

Cookies will not become visible until the next loading of a page that the cookie should be visible for. To test if a cookie was successfully set, check for the cookie on a next loading page before the cookie expires. Expire time is set via the expire parameter. A nice way to debug the existence of cookies is by simply calling print_r($_COOKIE);.

Cookies must be deleted with the same parameters as they were set with. If the value argument is an empty string, or FALSE, and all other arguments match a previous call to setcookie, then the cookie with the specified name will be deleted from the remote client. This is internally achieved by setting value to 'deleted' and expiration time to one year in past.

Because setting a cookie with a value of FALSE will try to delete the cookie, you should not use boolean values. Instead, use 0 for FALSE and 1 for TRUE.

Which should be enough for you to get a clear idea on whatyou've done wrong with your cookies:

  • Also read:

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 an associated cause is that your string cookie content value is looking like a boolean variable (due to PHP generally loose type casting), so try using a numeric equivilant boolean value 0 or 1 and that should appear correctly.

So:

  if(setcookie("loggedIn", 1, time() + 3600, "/", "", false, true)){
     print "Biscuit has been set!";
  } 

And after a page reload (note you should update your code check further up this code sample to look [more] similar to this piece here):

  if($_COOKIE['loggedIn'] == true){
       //cookie exists!
  }

If you are still having problems then I recommend using PHP Error logging and/or print_r($_COOKIE); at the top of your PHP page.

  • Use Sessions. They're much easier and safer.
Community
  • 1
  • 1
Martin
  • 22,212
  • 11
  • 70
  • 132