简体   繁体   中英

How can I make my CAPTCHA script have a refresh link?

I have a captcha script and it works good. But, I don't know how to make it refresh.

Here's verificationimage.php :

<?php

header('Content-type: image/jpeg');

$width = 50;
$height = 24;

$my_image = imagecreatetruecolor($width, $height);

imagefill($my_image, 0, 0, 0xFFFFFF);

// add noise
for ($c = 0; $c < 40; $c++){
    $x = rand(0,$width-1);
    $y = rand(0,$height-1);
    imagesetpixel($my_image, $x, $y, 0x000000);
    }

$x = rand(1,10);
$y = rand(1,10);

$rand_string = rand(1000,9999);
imagestring($my_image, 5, $x, $y, $rand_string, 0x000000);

setcookie('tntcon',(md5($rand_string).'a4xn'));

imagejpeg($my_image);
imagedestroy($my_image);
?>

And, the page with the form:

<label for="verif_box" style="margin-top:10px;">Image Verification:</label>

<input name="verif_box" type="text" id="verif_box" autocomplete="off" minlength="4" maxlength="5" class="text" />

<img id="captcha" src="verificationimage.php?<?php echo rand(0,9999);?>" alt="This form can't be submitted because images aren't displayed" title="Verification image, type it in the box" width="50" height="24" align="absbottom" onclick="$('#verif_box').focus();" style="cursor:pointer;" /> &nbsp; (<a href="#captcha" class="fancybox">what's this?</a>)
<br />
<br />

    <?php 
    //if the variable "wrong_code" is sent from previous page then display the error field
    if(isset($_GET['wrong_code'])){?>
    <div style="border:1px solid #990000; background-color:#D70000; color:#FFFFFF; padding:4px; padding-left:6px;width:295px;">The code you entered does not match the image. Please try typing what you see in the image to the right again.</div><br /> 
    <?php ;} ?>

Here is what happens in mailer.php :

// check to see if verificaton code was correct
if(md5($verif_box).'a4xn' == $_COOKIE['tntcon']){
    // if verification code was correct send the message and show this page

    mail("email@domain.com", 'New WeeBuild Support Ticket: '.$subject, $emailContent, $headers);

    mail($email, 'Thank you for contacting WeeBuild Support! (#'.$ticket.')', $emailContents, $headers2);

    // add to database

    $today = getdate();
        $theDate = $today["weekday"].", ".$today["month"]." ".$today["mday"].", ".$today["year"];

    mysql_select_db("database_name", $con);
        $sql="INSERT INTO table_name (name, email, subject, message, ticket, ip_address, created)
        VALUES ('$_POST[name]','$_POST[email]','$_POST[subject]','$_POST[message]','$ticket','$_SERVER[REMOTE_ADDR]','$theDate')";

if (!mysql_query($sql,$con))
  {
  die('Error: ' . mysql_error());
  }

  //close the database connection
  mysql_close($con);

    // delete the cookie so it cannot sent again by refreshing this page
    setcookie('tntcon','');

} else if(isset($message) and $message!=""){

    // if verification code was incorrect then return to contact page and show error

    header("Location: index.php?name=$name&subject=$subject&email=".urlencode($email)."&message=".urlencode($message)."&wrong_code=true");
    exit;
}

It all currently works great, but how can I make the captcha refresh? I tried doing this:

<script>
$(document).ready(function() {
$('#refresh').click(function() {
$('img#captcha').attr('src','verificationimage.php?<?php echo rand(0,9999);?>');
});
});
</script>
<a href="#" id="refresh">refresh</a>

But, it doesn't work.

By the way, I don't want to use reCaptcha, I just rather do it this way because reCaptcha, to me, looks hard to set up with my stuff.

My answer is similar to the one in the comments, likely a cached copy is being used on the refresh, but it'd be cleaner to use a proper method to make sure the browser doesn't cache that image rather than a random string. On the image generation page, add this:

header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");

Since the image tag has an id, that's the only thing you'll need for the selector.
I think the problem comes from browser caching : because the random string is generated by PHP the refresh button will work only once (since the next calls will use the same string, the browser will use the cached version instead).

This should do the trick, a new random string is generated everytime the button is pressed :

$(function() {
    $('#refresh').click(function() {
        $('#captcha').attr('src', 'verificationimage.php?' + new Date().getTime());
        return false;
    });
});

There are better, more secure ways to send the CAPTCHA information for verification besides using a cookie. At the very least, I would suggest using a session variable, but with a named session and IP verification, to prevent session hijacking. It would also be a VERY good idea to add hotlinking prevention to your CAPTCHA image generation script, so that someone can't just pull up the CAPTCHA image in a browser, all by itself. just a suggestion. :)

In order to use hotlink prevention, just add the following code to the top of the image creation script:

if (!isset($_SERVER['HTTP_REFERER']) or checkValidReferer() === false) die();

function checkValidReferer() {
  $out = false;
  $ref = $_SERVER['HTTP_REFERER'];
  $lh = $_SERVER['HTTP_HOST'];
  if (stripos($ref,$lh) !== false) $out = true;
  return $out;
}

The above code outputs a good image, if the base URL of the referrer both exists, and is identical to the base URL of the image script. This prevents the image from being used somewhere other than where it's supposed to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM