1

What I'm trying to do is a secret link for example website.com/?secret=yes when they visit this page i want to remove this variable from URL so I have the following:

<?php
if(isset($_GET['secret']) && $_GET['secret'] === 'yes') {
    header('Location: http://website.com');
    $secret="yes"; <--take note this is what I'm testing 
}
?>

The above code will redirect instantly so there is no variable in url and I tryed to make this variable myself with $secret="yes"; to be able to use it with the following code:

<?php if( 'yes' === $secret ) : ?>
secret content here
 <?php endif; ?>

Is this possible? How can I make my code work? I do not want to use session because I want it to do this only once, or everytime they access via the secret link, if they access without it don't show.

Boris Daka
  • 603
  • 2
  • 17
  • 33

3 Answers3

5

No, that won't work. Variables do not persist through reloading pages. You can however use sessions or cookies to do this:

<?php
session_start();
if(isset($_GET['secret']) && $_GET['secret'] === 'yes') {
    $_SESSION['secret']="yes";
    header('Location: http://website.com');
    exit();
}
?>

<?php if( $_SESSION['secret']=='yes'){ 
unset($_SESSION['secret']); //unset so when the page reloads the secret data will be gone
?>
secret content here
 <?php } ?>
Tim Withers
  • 12,072
  • 5
  • 43
  • 67
  • 3
    +1 for Sessions. The user has absolutely no clue what is in the Session variables, just that there is one somewhere. Just don't forget to `die()` or `exit` after setting the location header, and ideally for readability the `$_SESSION['secret']='yes'` should be before the `header()`. – Niet the Dark Absol Dec 06 '12 at 05:16
  • 3
    You may also want to `exit;` after the session variable is set, to make sure that no code below executes when it shouldn't. – John V. Dec 06 '12 at 05:17
  • Aha this is nice too I didn't know there is unset for SESSION! – Boris Daka Dec 06 '12 at 05:17
  • Thanks a lot for the solution i will use it – Boris Daka Dec 06 '12 at 05:33
  • @TimWithers If I have secret content in few parts of the page should I use more Sessions? Like $_SESSION['secret2']="yes"; and unset it as well? – Boris Daka Dec 06 '12 at 06:05
  • @MarkVoidale You can do multi-dimensional arrays if you want: `$_SESSION['secrets'][1]='yes';` and then unset them all: `unset($_SESSION['secrets']);` at the end of the page. – Tim Withers Dec 08 '12 at 14:35
1

You can achieve by another way as below.

Create a text file like skey.txt

and write code as below :

 $filename = 'skey.txt';
if(isset($_GET['secret']) && $_GET['secret'] === 'yes') {
    $data = file_get_contents($filename);
    header('Location: http://localhost/'.$_SERVER['PHP_SELF']);
    file_put_contents($filename, $data."\n".$_SERVER['REMOTE_ADDR'].'secret=yes');
}

or

$filename = 'skey.txt';
if(isset($_GET['secret']) && $_GET['secret'] === 'yes') {
    $data = file_get_contents($filename);
    file_put_contents($filename, $data."\n".$_SERVER['REMOTE_ADDR'].'secret=yes');
    header('Location: http://localhost/'.$_SERVER['PHP_SELF']);
}

when you will be redirected to a page. you can check it as below :

$data = file($filename);
if(!empty($data) && in_array($_SERVER['REMOTE_ADDR'].'secret=yes', $data)) {
    echo 'hello';
    $getlines = array_keys($data, $_SERVER['REMOTE_ADDR'].'secret=yes');
    foreach($getlines as $lkey) {
        unset($data[$lkey]);
    }

    file_put_contents($filename, implode("\n", $data));
}

I think it will work for you...

  • 2
    This won't work because that same file would be there for anyone accessing the site after someone else had accessed the secret URL. If you really wanted to go down this path, you could use the IP address or some other unique detail as (part of) the filename. Or, you could just use the Session as in the other answer, and get a better result more simply. – Dallin Dec 06 '12 at 05:43
0

Because of the stateless nature of HTTP, you'll need to pass the secret token one way or the other. If you want to ensure that the content is accessed once you could do an MD hash of some unique info (IP, user agent, etc) and pass that around. You should be able to add your variables to the header call:

header('Location:http://website.com/?secret=yes');

note that you'd be checking the value with

<?php if ($_GET['secret'] == "yes"): ?>


// secret content
<?php endif; ?>

This is not a secure solution because anyone can just append ?sectet=true to the link, a hash would be better because it's can be a combination of things. If you decide to go with a hash make sure you're using salt, or you may risk a collision / rainbow table attack

Piotr Kaluza
  • 413
  • 2
  • 7
  • Hash seems like interesting approach my website is already heavy, Is this approach will slow it down even more? – Boris Daka Dec 06 '12 at 05:27
  • Not signigicantly, actually SESSIONS use hashes internally, however you had said that you don't want to use SESSIOS. The technique I am talking about is known as token based authentication. That being said, Tim's excellent solution above seems the easiest route – Piotr Kaluza Dec 06 '12 at 15:18