1

I want to generate a random key for the user to use during registration. The code compares the generated key with the user input but the key gets regenerated when the user submits the form, so they are never the same. I tried to protect the generator function by checking if it was already generated but it didn't work. Then, I tried to use session as well, which didn't work either. Here's the code which always produces "fail" rather than "success":

Edit: I made some corrections according to your comments.

<?php
session_start();
$_SESSION['key'] = randomKey();
$key1 = $_SESSION['key'];
error_reporting(E_ALL);
ini_set('display_errors', 1);

function randomKey() {

    if (empty($_SESSION['key'])) {
        $key = uniqid();
        $_SESSION['key'] = $key;
        return $key;
    } else {
        return $_SESSION['key'];
    }
}

if(isset($_POST['submit']))
{   
    $input = $_POST['inputKey'];
    if (strcmp($input,$_SESSION['key']) == 0) {
    echo 'success';
    } else {
    echo 'fail';
    }
}
?>
<html>
<head>
</head>
<body>
<form method="POST" action="">
<table border="0">
<tr>
<td>Your key:</td>
<td>
<b>
<?php echo $key1; ?></b>
</td>
</tr>
<tr>
<td>Enter your key:</td><td><input type="text" name="inputKey"></td>
</tr>
<tr>
<td><input id="button" type="submit" name="submit" value="Sign-Up"></td>
</tr>
</table>
</form>
</body>
</html>
ezekeel
  • 23
  • 1
  • 5
  • Unless you pass $key into your function, it will always be null, so you'll always get a new one. Read this http://php.net/manual/en/language.variables.scope.php – rjdown Aug 04 '16 at 23:13
  • 1
    $_session -> $_SESSSION –  Aug 04 '16 at 23:21
  • @rjdown but he is using the session global –  Aug 04 '16 at 23:23
  • http://php.net/manual/en/language.variables.superglobals.php read that. and while you're at it http://php.net/manual/en/function.error-reporting.php – Funk Forty Niner Aug 04 '16 at 23:26
  • @rjdown Thank you. $key is already in the function. So, I move it outside the function and check it in the randomKey() function like this: `$key; function randomKey() { global $key; if ($key == null) { $key = uniqid(); return $key; } else { return $key; } }` I still get "fail". – ezekeel Aug 04 '16 at 23:29
  • stop using global; its almost always a bad idea –  Aug 04 '16 at 23:30
  • @Fred-ii- Were you pointing at the undefined variable? I also added a php.ini and error reporting code as you mentined. – ezekeel Aug 05 '16 at 00:16
  • @Dagon I don't know how I can keep the variables because I lose them when I submit it. Session globals didn't solve the problem, though. – ezekeel Aug 05 '16 at 00:18
  • By the way, I made some corrections as you suggested but I'm a bit confused, maybe I misinterpreted them. – ezekeel Aug 05 '16 at 00:20
  • Yes I was. I reopened the question. Are you getting any errors at all now? look at your html source and var_dump stuff to see what you get. Plus, I cant test this, I am not at my dev pc. – Funk Forty Niner Aug 05 '16 at 00:23
  • HTML stickler: `
    ` cannot be child of ``. Important html tidbit.
    – Funk Forty Niner Aug 05 '16 at 00:28
  • @Fred-ii- I've corrected that nesting now. Yes, I'm getting this: "Cannot send session cache limiter - headers already sent by (output started at . . ." I have found a solution on the Internet ("To resolve this error remove the lines from the PHP code that are printing to the browser prior to sending headers") but it didn't work. It's the only error I can see in the log. I tried moved the PHP codes inside the body tag but it just keeps giving the same error by just changing the error line. – ezekeel Aug 05 '16 at 00:43
  • 1
    Read this on the headers sent http://stackoverflow.com/questions/9707693/warning-cannot-modify-header-information-headers-already-sent-by-error – Funk Forty Niner Aug 05 '16 at 01:04

2 Answers2

1

You stated in comments that there was now a headers sent warning.

The following link will help you figure out why that is.

However, I did find a slight bug in your code.

Even upon success, your code will produce the same key when the page is reloaded; where "randomness" would literally be "thrown out the window", since that is what the whole purpose is with your usage of the unique function.

You need to destroy the session on success.

Here is what your code should look like and using session_destroy():

if(isset($_POST['submit']))
{   
    $input = $_POST['inputKey'];
    if (strcmp($input,$_SESSION['key']) == 0) {

    echo 'success';

    session_destroy();

    } else {
    echo 'fail';
    }
}

Reference:

Once you've corrected the problem with the headers being sent, consider redirecting somewhere (or the same page for that matter), after succession.

You can do this with a header, but you cannot echo and use a header at the same time, so remember that.

Reference:

and be sure to add an exit; after the header (as stated in the manual), otherwise your code may want to continue to execute and if you have more code below it.

Community
  • 1
  • 1
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
0

Sorry, for the delay. I think I've found a workaround. I just posted the form to another page which grabs and controls the information. That way, the random code isn't regenerated. So, I have two pages instead of one.

test1.php:

<?php

$key = randomKey();

function randomKey() {

    $i = 0;
    do {
    $key = uniqid();
        return $key;
    } while ($i > 0);
}
?>
<html>
<head>
</head>
<body>
<form method="POST" action="randomkey2.php">
<table border="0">
<tr>
<td>Your key:</td>
<td>
<b>
<?php echo $key?></b><input type="hidden" name="keyHidden" value="<?php echo $key;?>" />
</td>
</tr>
<tr>
<td>Enter your key:</td><td><input type="text" name="inputKey"></td>
</tr>
<tr>
<td><input id="button" type="submit" name="submit" value="Sign-Up"></td>
</tr>
</table>
</form>
</body>
</html>

test2.php:

<?php

$input = $_POST['inputKey'];
$key = $_POST['keyHidden'];

$control = strpos($key, $input);

if($control !== false)
{   
echo 'success';
} else {
echo 'fail';
}

?>

This way, I also don't have to use session globals. Well, this may look a bit odd but the process is normally a bit more complicated and it requires to give some instructions. So, subdividing the process isn't a problem for me and it works. I'm sorry if I've wasted your time, I've just started to fiddle with PHP. Thank you for your corrections and suggestions.

ezekeel
  • 23
  • 1
  • 5