PHP Captcha without session

后端 未结 13 1654
傲寒
傲寒 2021-01-04 13:51

Ok, here is an issue: in the project i\'m working on, we can\'t rely on server-side sessions for any functionality.

The problem is that common captcha solutions fro

相关标签:
13条回答
  • 2021-01-04 14:19

    just make a math captcha ;) 2+90 = ? equation should be shown in an image and voila ;)

    0 讨论(0)
  • 2021-01-04 14:20

    Make your hidden input field just a random sequence. Store this random data in the database along with the captcha information, so you can look up the correct captcha with it.

    You will also need to set a short-ish time to live for each captcha generated. Finally, you can store and track in the database the number of attempts on each captcha and impose a hard limit on it (3 guesses and it is a permanent fail).

    0 讨论(0)
  • 2021-01-04 14:21

    Use the honeypot technique: place a text field with a greedy name, as 'email', into an field hidden by CSS (display: none; visibility: hidden;).

    When you have to sanitize the form, simply check if that field is empty, is being send by an human (that cant see the field and so cant fill it up), else, from a spammer.

    That's why usually spammer use to fill up all the fields in the page with predefinited values before sending the form... and doesnt bother the user for reading the captcha.

    Else, rely on the human reading, something like "Write the first $x letter of the word "$word" in the field:"

    Then, you only have to send the $x and $word to the next page and check it (and of course, you can randomize the fields name to be more accurated)

    I remember that a plugin for phpBB forum rely on the fact that, usually, the spam bots selects the first option avaiable (with a value) in the <select> fields; Just put as first option <option value="kickmeplease">Yes, im a bot.</option>

    There are many ways to protect against spambots, playing on one factor that bots will never have: imagination

    0 讨论(0)
  • 2021-01-04 14:21

    Form with validation:

    $errorsucc = '';
    
    if (isset($_POST["captcha_check"])) {
    
        $code = str_decrypt($_POST["captcha_check"]);   
    
        if (empty($_POST['captcha_code'])) { 
            $errorsucc = '<p style="color:red">Please Enter the security code.</p>';
    
        } elseif(!( $code == $_POST['captcha_code'] && !empty($code) )) {
            $errorsucc = '<p style="color:red">Incorrect Code Entered.</p>';
    
        } else {
            $errorsucc = '<p style = "green">Nice, you entered the correct code.</p>';  
        }
    }
    
    $captcha = new CaptchaCode();
    $code = str_encrypt($captcha->generateCode(6));
    ?>
    
    <html>
        <title>Sessionless Captcha</title>
        <div style = "background: #e2e2e2; padding: 20px; width: 20%; box-shadow: 5px 5px #ccc;">
            <?php echo $errorsucc; ?>
            <form name="captchaform" method="post">
                <table border="0" cellpadding="4" cellspacing="0">
                    <tr><td valign="middle" align="left">Security Code:</td>
                        <td valign="middle" align="left"><img src="captcha_images.php?width=150&height=50&code=<?php echo $code?>" /></td>
                    </tr>
                    <tr><td valign="middle" align="left">Enter Code:</td>
                        <td valign="middle" align="left"><input id="captcha_code" name="captcha_code" style="width:150px" type="text" /></td>
                    </tr>
    
                    <tr><td valign="top" align="left">
                        </td>
                        <td valign="top" align="left">
                            <input border="0" type="submit" value="Submit" />   
                        </td>
                    </tr>
                </table>
                <input type="hidden" name="captcha_check" value="<?php echo $code?>" />
            </form>
        </div>
    </html>
    

    Generate images just like any other captcha:

    /* font size will be 75% of the image height */
        $font_size = $height * 0.75;
        $image = @imagecreate($width, $height) or die('Cannot initialize new GD image stream');
        /* set the colours */
        $background_color = imagecolorallocate($image, 255, 255, 255);
        $text_color = imagecolorallocate($image, 0, 26, 26);
        $noise_color = imagecolorallocate($image, 25, 89, 89);
        /* generate random dots in background */
        for( $i=0; $i<($width*$height)/3; $i++ ) {
            imagefilledellipse($image, mt_rand(0,$width), mt_rand(0,$height), 1, 1, $noise_color);
        }
        /* generate random lines in background */
        for( $i=0; $i<($width*$height)/150; $i++ ) {
            imageline($image, mt_rand(0,$width), mt_rand(0,$height), mt_rand(0,$width), mt_rand(0,$height), $noise_color);
        }
        /* create textbox and add text */
        $textbox = imagettfbbox($font_size, 0, $this->font, $code) or die('Error in imagettfbbox function');
        $x = ($width - $textbox[4])/2;
        $y = ($height - $textbox[5])/2;
        imagettftext($image, $font_size, 0, $x, $y, $text_color, $this->font , $code) or die('Error in imagettftext function');
        /* output captcha image to browser */
        header('Content-Type: image/jpeg');
        imagejpeg($image);
        imagedestroy($image);
    

    Download the demo files from this link: Create a Sessionless Captcha in PHP

    0 讨论(0)
  • 2021-01-04 14:22

    The need for session or database comes from the need to coordinate the GET for the image with the html page containing it, so how about use the same code to embed a captcha image: [img src='data:image/jpeg;base64,...'], use a random salt to hash its text, then sending the random salt and hash together with the image to the client in a single GET?

    On postback you append the user text to the salt then compare the hashes. Just wondering how safe this would be...

    0 讨论(0)
  • 2021-01-04 14:28

    Can you grant them a client certificate in response to a CAPTCHA call? Then once they select that certificate in the browser it's sent with each call from the client, and can be used for authentication without sessions and without further CAPTCHA calls.

    0 讨论(0)
提交回复
热议问题