-2

I have a form and when the users enter "Test" it should create a cookie and load the templates using require function. As soon as the cookie is enabled it will display the template. If the cookie expires it will require again the password. In other words, i if the password is "Test" i want to include that template for 12 hour to the user's browser before asking again for the password.

Below is what i am trying. More about cookies here

Problem is that the cookie idea is not working.

     <?php
        if ($_SERVER["REQUEST_METHOD"] == "POST") {
        $code = $_POST["SecretCode"];
        }



        if( $code === "test") {
        $cookie_name = "user";
        $cookie_value = "Cookie"; 
        setcookie($cookie_name, $cookie_value, time() + (1000 * 10), "/"); // 86400 = 1 day
        if(isset($_COOKIE[$cookie_name])) {
        require_once 'template.php';
//echo 'cookie set:'.$_COOKIE[$cookie_name];
        } 
        }?>

        <form method="post" action='<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>'>
        <input name="SecretCode" type="text" required>
        <button>Check password</button>
        </form>
  • is there any html output before the php that tries to set the cookie? – Professor Abronsius Mar 12 '18 at 08:16
  • The problem i have is that the cookie idea is not working. If you comment everything that has to do with cookies and try how it works you will get an idea. All i want to do is clear. The user will enter a password, then if the password is correct the template will be loaded to his browser. I just want to implement cookies. –  Mar 12 '18 at 08:18
  • check the php error log – Professor Abronsius Mar 12 '18 at 08:20
  • you don't help me at all –  Mar 12 '18 at 08:24
  • I have asked if there was any html before `setcookie` - no reply so I asked you to check the error log. Using `setcookie` after any html output will cause an error – Professor Abronsius Mar 12 '18 at 08:42
  • @Progrock $_COOKIE is `global variable` –  Mar 12 '18 at 08:43
  • @RamRaider my code is as shown above. No html above setcookie and no errors –  Mar 12 '18 at 08:46
  • Some nitpicks: 'test' !== 'Test', and 12 hours is not the same as 10000 or 86400 seconds. – Progrock Mar 12 '18 at 09:12

2 Answers2

1

Your cookie value within the $_COOKIE superglobal will not be populated until the next page request.

When you use setcookie the server will attempt to send a cookie to the client. If the cookie has not expired upon subsequent client requests, the client will present that cookie. Php will then use this value to populate the $_COOKIE superglobal.

In other words: setcookie('foo', 'bar', etc) does not immediately populate $_COOKIE['foo'].

You currently nest your template call like this:

if($code === "test") {
    if(isset($_COOKIE[$cookie_name])) {
        require_once 'template.php';
    }
}

This requires that your secret is 'test' (from a form post) and that $_COOKIE['user'] is set. Your template therefore will not get included unless you submit your form with the correct value after the cookie has already been set (at least two successful form submissions and validations).

If you redirect after setcookie you can then rely moreso upon $_COOKIE. Do note that cookies can be spoofed:

<?php

$cookie_name   = "user";
$cookie_value  = "Cookie";

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $secret = isset($_POST['secret']) ? $_POST['secret'] : null;
    $forget = isset($_POST['forget']) ? $_POST['forget'] : null;

    if($secret === "test") {
        $cookie_expiry = time() + (24*60*60); // +1 day
        setcookie($cookie_name, $cookie_value, $cookie_expiry , "/");
        // Redirect here.
        exit;
    }
    if($forget) {
        $cookie_expiry = time() - (24*60*60); // -1 day
        setcookie($cookie_name, '', $cookie_expiry , "/");
        // Redirect here.
        exit;
    }
}
if(isset($_COOKIE[$cookie_name])) {
    echo 'Cookie set.';
} 
?>
<form method="post" action='<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>'>
    <label for="secret">Secret:</label>
    <input name="secret" type="text" required>
    <input type="submit" value="Check in">
</form>
<form method="post">
    <input type="submit" name="forget" value="Forget me">
</form>
Progrock
  • 7,373
  • 1
  • 19
  • 25
0

This will also work:

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$cookieName = 'User';

if (isset($_POST['SecretCode']) && ($_POST['SecretCode'] == 'test')) {
  echo 'Password correct.<br>';
  setcookie($cookieName,'Cookie',time()+86400,'/'); // 86400 = 1 day
  echo 'Cookie was set.<br>';
  echo 'Require template here.<br>';
}  elseif (isset($_COOKIE[$cookieName])) {
  echo 'Require template here as well.<br>';
  echo 'Cookie value: ['.$_COOKIE[$cookieName].']<br>';
}

?>

<form method="post">
<input name="SecretCode" type="text" required>
<button>Check password</button>
</form>
KIKO Software
  • 15,283
  • 3
  • 18
  • 33
  • there is one issue. I need to submit the password 3 times to work. And when i delete my browser's cache cookies are set –  Mar 12 '18 at 09:04
  • I don't understand why you would need to submit the password three times? Did you type it correctly? The cache and cookies are two different things. Which browser are you using? – KIKO Software Mar 12 '18 at 09:10
  • @Progrock: I followed your advice. – KIKO Software Mar 12 '18 at 09:13
  • @KIKOSoftware, that echo line is still above setcookie here for me. – Progrock Mar 12 '18 at 09:14
  • I don't know neither sometimes it proceeds with 1 submit sometimes it needs two clicks to load the template @KIKOSoftware. Actually when i hit enter it needs two times. When i click the button it proceed normally –  Mar 12 '18 at 09:29
  • You have used `require_once('template.php');` in the **two** places I indicated? – KIKO Software Mar 12 '18 at 09:34
  • I use `include` inside both if statements. Now your code is correct, it does not include twice. Thank you –  Mar 12 '18 at 10:46
  • Last issue i noticed, when i reload the page the form resubmits the input value and the cookies are set again. –  Mar 12 '18 at 11:03