Page 1 of 10 123 ... Last
  • Jump to page:
    #1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    451
    Rep Power
    8

    A more advanced Login system with password forgot


    Hi,

    since a lot of people are asking for a login system with a password forgot function, but still is secure, I will post the files I have made with the useful help of some other users of this forum.

    The files are posted as a zip file and as text under this post.

    If there are any bugs, please put them on this Thread so I know what could be better.

    I hope you will find it useful.

    NOTE that you need access to /dev/urandom! Otherwise your hashing library won't work or it will use a very weak number that should be secure. This login system also requires PHP 5.3.7 or later.

    lib/class.phpmailer.php:
    This file is too big to include it like the others, to see the script check this

    lib/functions:
    PHP Code:
    <?php 
        
    function generate_secure_token($length 16) { 
            return 
    bin2hex(openssl_random_pseudo_bytes($length));                           // important! this has to be a crytographically secure random generator 
        


        function 
    html_escape($raw_input) { 
            return 
    htmlspecialchars($raw_inputENT_QUOTES ENT_HTML401'UTF-8'); 
        }
    lib/mail.php:
    PHP Code:
    <?php
    function mail_f ($mail_to$mail_subject$mail_body)
    {
    require 
    'class.phpmailer.php';

    $mail             = new PHPMailer(); 

    $body             preg_replace('/\[\]/','',$mail_body);

    $mail->SetFrom('noreply@domain.com''Domain');

    $mail->AddReplyTo("noreply@domain.com","Domain");

    $mail->AddAddress($mail_to);

    $mail->Subject    $mail_subject;

    $mail->AltBody    "To view the message, please use an HTML compatible email viewer!"// optional, comment out and test

    $mail->MsgHTML($body);

    if(!
    $mail->Send()) {
      
    $succes 0;

    else {
      
    $succes 1;
    }
    return 
    $succes;

    }

    ?>
    lib/password.php:
    PHP Code:
    <?php
    /**
     * A Compatibility library with PHP 5.5's simplified password hashing API.
     *
     * @author Anthony Ferrara <ircmaxell@php.net>
     * @license http://www.opensource.org/licenses/mit-license.html MIT License
     * @copyright 2012 The Authors
     */

    if (!defined('PASSWORD_BCRYPT')) {

        
    define('PASSWORD_BCRYPT'1);
        
    define('PASSWORD_DEFAULT'PASSWORD_BCRYPT);

        
    /**
         * Hash the password using the specified algorithm
         *
         * @param string $password The password to hash
         * @param int    $algo     The algorithm to use (Defined by PASSWORD_* constants)
         * @param array  $options  The options for the algorithm to use
         *
         * @return string|false The hashed password, or false on error.
         */
        
    function password_hash($password$algo, array $options = array()) {
            if (!
    function_exists('crypt')) {
                
    trigger_error("Crypt must be loaded for password_hash to function"E_USER_WARNING);
                return 
    null;
            }
            if (!
    is_string($password)) {
                
    trigger_error("password_hash(): Password must be a string"E_USER_WARNING);
                return 
    null;
            }
            if (!
    is_int($algo)) {
                
    trigger_error("password_hash() expects parameter 2 to be long, " gettype($algo) . " given"E_USER_WARNING);
                return 
    null;
            }
            switch (
    $algo) {
                case 
    PASSWORD_BCRYPT:
                    
    // Note that this is a C constant, but not exposed to PHP, so we don't define it here.
                    
    $cost 10;
                    if (isset(
    $options['cost'])) {
                        
    $cost $options['cost'];
                        if (
    $cost || $cost 31) {
                            
    trigger_error(sprintf("password_hash(): Invalid bcrypt cost parameter specified: %d"$cost), E_USER_WARNING);
                            return 
    null;
                        }
                    }
                    
    $required_salt_len 22;
                    
    $hash_format sprintf("$2y$%02d$"$cost);
                    break;
                default:
                    
    trigger_error(sprintf("password_hash(): Unknown password hashing algorithm: %s"$algo), E_USER_WARNING);
                    return 
    null;
            }
            if (isset(
    $options['salt'])) {
                switch (
    gettype($options['salt'])) {
                    case 
    'NULL':
                    case 
    'boolean':
                    case 
    'integer':
                    case 
    'double':
                    case 
    'string':
                        
    $salt = (string) $options['salt'];
                        break;
                    case 
    'object':
                        if (
    method_exists($options['salt'], '__tostring')) {
                            
    $salt = (string) $options['salt'];
                            break;
                        }
                    case 
    'array':
                    case 
    'resource':
                    default:
                        
    trigger_error('password_hash(): Non-string salt parameter supplied'E_USER_WARNING);
                        return 
    null;
                }
                if (
    strlen($salt) < $required_salt_len) {
                    
    trigger_error(sprintf("password_hash(): Provided salt is too short: %d expecting %d"strlen($salt), $required_salt_len), E_USER_WARNING);
                    return 
    null;
                } elseif (
    == preg_match('#^[a-zA-Z0-9./]+$#D'$salt)) {
                    
    $salt str_replace('+''.'base64_encode($salt));
                }
            } else {
                
    $buffer '';
                
    $raw_length = (int) ($required_salt_len 1);
                
    $buffer_valid false;
                if (
    function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
                    
    $buffer mcrypt_create_iv($raw_lengthMCRYPT_DEV_URANDOM);
                    if (
    $buffer) {
                        
    $buffer_valid true;
                    }
                }
                if (!
    $buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
                    
    $buffer openssl_random_pseudo_bytes($raw_length);
                    if (
    $buffer) {
                        
    $buffer_valid true;
                    }
                }
                if (!
    $buffer_valid && is_readable('/dev/urandom')) {
                    
    $f fopen('/dev/urandom''r');
                    
    $read strlen($buffer);
                    while (
    $read $raw_length) {
                        
    $buffer .= fread($f$raw_length $read);
                        
    $read strlen($buffer);
                    }
                    
    fclose($f);
                    if (
    $read >= $raw_length) {
                        
    $buffer_valid true;
                    }
                }
                if (!
    $buffer_valid || strlen($buffer) < $raw_length) {
                    
    $bl strlen($buffer);
                    for (
    $i 0$i $raw_length$i++) {
                        if (
    $i $bl) {
                            
    $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0255));
                        } else {
                            
    $buffer .= chr(mt_rand(0255));
                        }
                    }
                }
                
    $salt str_replace('+''.'base64_encode($buffer));

            }
            
    $salt substr($salt0$required_salt_len);

            
    $hash $hash_format $salt;

            
    $ret crypt($password$hash);

            if (!
    is_string($ret) || strlen($ret) <= 13) {
                return 
    false;
            }

            return 
    $ret;
        }

        
    /**
         * Get information about the password hash. Returns an array of the information
         * that was used to generate the password hash.
         *
         * array(
         *    'algo' => 1,
         *    'algoName' => 'bcrypt',
         *    'options' => array(
         *        'cost' => 10,
         *    ),
         * )
         *
         * @param string $hash The password hash to extract info from
         *
         * @return array The array of information about the hash.
         */
        
    function password_get_info($hash) {
            
    $return = array(
                
    'algo' => 0,
                
    'algoName' => 'unknown',
                
    'options' => array(),
            );
            if (
    substr($hash04) == '$2y$' && strlen($hash) == 60) {
                
    $return['algo'] = PASSWORD_BCRYPT;
                
    $return['algoName'] = 'bcrypt';
                list(
    $cost) = sscanf($hash"$2y$%d$");
                
    $return['options']['cost'] = $cost;
            }
            return 
    $return;
        }

        
    /**
         * Determine if the password hash needs to be rehashed according to the options provided
         *
         * If the answer is true, after validating the password using password_verify, rehash it.
         *
         * @param string $hash    The hash to test
         * @param int    $algo    The algorithm used for new password hashes
         * @param array  $options The options array passed to password_hash
         *
         * @return boolean True if the password needs to be rehashed.
         */
        
    function password_needs_rehash($hash$algo, array $options = array()) {
            
    $info password_get_info($hash);
            if (
    $info['algo'] != $algo) {
                return 
    true;
            }
            switch (
    $algo) {
                case 
    PASSWORD_BCRYPT:
                    
    $cost = isset($options['cost']) ? $options['cost'] : 10;
                    if (
    $cost != $info['options']['cost']) {
                        return 
    true;
                    }
                    break;
            }
            return 
    false;
        }

        
    /**
         * Verify a password against a hash using a timing attack resistant approach
         *
         * @param string $password The password to verify
         * @param string $hash     The hash to verify against
         *
         * @return boolean If the password matches the hash
         */
        
    function password_verify($password$hash) {
            if (!
    function_exists('crypt')) {
                
    trigger_error("Crypt must be loaded for password_verify to function"E_USER_WARNING);
                return 
    false;
            }
            
    $ret crypt($password$hash);
            if (!
    is_string($ret) || strlen($ret) != strlen($hash) || strlen($ret) <= 13) {
                return 
    false;
            }

            
    $status 0;
            for (
    $i 0$i strlen($ret); $i++) {
                
    $status |= (ord($ret[$i]) ^ ord($hash[$i]));
            }

            return 
    $status === 0;
        }
    }
    lib/rnum.php:
    PHP Code:
    <?php 
        
    /** 
     * Generate a relatively secure hex encoded pseudo random number. 
     * 
     * Code taken from the password_compat library by Anthony Ferrara (github.com/ircmaxell/password_compat). 
     * The resulting number is _not_ necessarily cryptographically secure. 
     * 
     * @param int $length The length of the resulting hex string 
     * 
     * @return string|boolean The hex string or false in case of an error 
     */ 
    function rnum($length 32) { 
        
    $length = (int) $length
        if (!
    $length) { 
            
    trigger_error('Invalid length for random string'E_USER_WARNING); 
            return 
    false
        } 
        
    $buffer ''
        
    $raw_length $length 2;        // the number of bytes 
        
    $buffer_valid false
        if (
    function_exists('mcrypt_create_iv') && !defined('PHALANGER')) { 
            
    $buffer mcrypt_create_iv($raw_lengthMCRYPT_DEV_URANDOM); 
            if (
    $buffer) { 
                
    $buffer_valid true
            } 
        } 
        if (!
    $buffer_valid && function_exists('openssl_random_pseudo_bytes')) { 
            
    $buffer openssl_random_pseudo_bytes($raw_length); 
            if (
    $buffer) { 
                
    $buffer_valid true
            } 
        } 
        if (!
    $buffer_valid && is_readable('/dev/urandom')) { 
            
    $f fopen('/dev/urandom''r'); 
            
    $read strlen($buffer); 
            while (
    $read $raw_length) { 
                
    $buffer .= fread($f$raw_length $read); 
                
    $read strlen($buffer); 
            } 
            
    fclose($f); 
            if (
    $read >= $raw_length) { 
                
    $buffer_valid true
            } 
        } 
        if (!
    $buffer_valid || strlen($buffer) < $raw_length) { 
            
    $bl strlen($buffer); 
            for (
    $i 0$i $raw_length$i++) { 
                if (
    $i $bl) { 
                    
    $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0255)); 
                } else { 
                    
    $buffer .= chr(mt_rand(0255)); 
                } 
            } 
        } 
        if (!
    $buffer_valid || strlen($buffer) < $raw_length) { 
            
    trigger_error('Could not generate random string'E_USER_WARNING); 
            return 
    false
        } 

        return 
    bin2hex($buffer); 
    }
    common.php:
    PHP Code:
    <?php 
        
    // These variables define the connection information for your MySQL database 
        
    $username "dbusername"
        
    $password "dbpassword"
        
    $host "localhost"
        
    $dbname "dbname"

        
    // UTF-8 is a character encoding scheme that allows you to conveniently store 
        // a wide varienty of special characters, like  or €, in your database. 
        // By passing the following $options array to the database connection code we 
        // are telling the MySQL server that we want to communicate with it using UTF-8 
        // See Wikipedia for more information on UTF-8: 
        // http://en.wikipedia.org/wiki/UTF-8 
        
    $options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); 
         
        
    // A try/catch statement is a common method of error handling in object oriented code. 
        // First, PHP executes the code within the try block.  If at any time it encounters an 
        // error while executing that code, it stops immediately and jumps down to the 
        // catch block.  For more detailed information on exceptions and try/catch blocks: 
        // http://us2.php.net/manual/en/language.exceptions.php 
        
    try 
        { 
            
    // This statement opens a connection to your database using the PDO library 
            // PDO is designed to provide a flexible interface between PHP and many 
            // different types of database servers.  For more information on PDO: 
            // http://us2.php.net/manual/en/class.pdo.php 
            
    $db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8"$username$password$options); 
        } 
        catch(
    PDOException $ex
        { 
            
    // If an error occurs while opening a connection to your database, it will 
            // be trapped here.  The script will output an error and stop executing. 
            // Note: On a production website, you should not output $ex->getMessage(). 
            // It may provide an attacker with helpful information about your code 
            // (like your database username and password). 
            
    die("Failed to connect to the database: " $ex->getMessage()); 
        } 
         
        
    // This statement configures PDO to throw an exception when it encounters 
        // an error.  This allows us to use try/catch blocks to trap database errors. 
        
    $db->setAttribute(PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION); 
         
        
    // This statement configures PDO to return database rows from your database using an associative 
        // array.  This means the array will have string indexes, where the string value 
        // represents the name of the column in your database. 
        
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODEPDO::FETCH_ASSOC); 
         
        
    // This block of code is used to undo magic quotes.  Magic quotes are a terrible 
        // feature that was removed from PHP as of PHP 5.4.  However, older installations 
        // of PHP may still have magic quotes enabled and this code is necessary to 
        // prevent them from causing problems.  For more information on magic quotes: 
        // http://php.net/manual/en/security.magicquotes.php 
        
    if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) 
        { 
            function 
    undo_magic_quotes_gpc(&$array
            { 
                foreach(
    $array as &$value
                { 
                    if(
    is_array($value)) 
                    { 
                        
    undo_magic_quotes_gpc($value); 
                    } 
                    else 
                    { 
                        
    $value stripslashes($value); 
                    } 
                } 
            } 
         
            
    undo_magic_quotes_gpc($_POST); 
            
    undo_magic_quotes_gpc($_GET); 
            
    undo_magic_quotes_gpc($_COOKIE); 
        } 
         
        
    // This tells the web browser that your content is encoded using UTF-8 
        // and that it should submit content back to you using UTF-8 
        
    header('Content-Type: text/html; charset=utf-8'); 
         
        
    // This initializes a session.  Sessions are used to store information about 
        // a visitor from one web page visit to the next.  Unlike a cookie, the information is 
        // stored on the server-side and cannot be modified by the visitor.  However, 
        // note that in most cases sessions do still use cookies and require the visitor 
        // to have cookies enabled.  For more information about sessions: 
        // http://us.php.net/manual/en/book.session.php 
        
    session_start(); 

        
    // Note that it is a good practice to NOT end your PHP files with a closing PHP tag. 
        // This prevents trailing newlines on the file from being included in your output, 
        // which can cause problems with redirecting users.
    edit_account.php:
    PHP Code:
    <?php 

        
    // First we execute our common code to connection to the database and start the session 
        
    require("common.php"); 
        
        require(
    "lib/password.php");
        require(
    "lib/functions.php");
        
        
    // At the top of the page we check to see whether the user is logged in or not 
        
    if(empty($_SESSION['user'])) 
        { 
            
    // If they are not, we redirect them to the login page. 
            
    header("Location: login.php"); 
             
            
    // Remember that this die statement is absolutely critical.  Without it, 
            // people can view your members-only content without logging in. 
            
    exit; 
        } 
         
        
    // This if statement checks to determine whether the edit form has been submitted 
        // If it has, then the account updating code is run, otherwise the form is displayed 
        
    if(!empty($_POST)) 
        { 
            if (isset(
    $_POST['action_token']) && isset($_SESSION['action_token']) && $_POST['action_token'] === $_SESSION['action_token']) 
            {
                
    // Make sure the user entered a valid E-Mail address 
                
    if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) 
                { 
                    exit; 
                } 

                
    // If the user is changing their E-Mail address, we need to make sure that 
                // the new value does not conflict with a value that is already in the system. 
                // If the user is not changing their E-Mail address this check is not needed. 
                
    if($_POST['email'] != $_SESSION['user']['email']) 
                { 
                    
    // Define our SQL query 
                    
    $email_check_stmt $db->prepare(
                        SELECT 
                            1 
                        FROM users 
                        WHERE 
                            email = :email 
                    '
    ); 

                    
    // Define our query parameter values 
                    
    $email_check_stmt->execute(array( 
                        
    ':email' => $_POST['email'
                    )); 


                    
    // Retrieve results (if any) 
                    
    $email_check $email_check_stmt->fetch(); 
                    if(
    $email_check
                    { 
                        die(
    "This E-Mail address is already in use"); 
                    } 
                } 

                
    // If the user entered a new password, we need to hash it
                // for good measure. 
                
    if(!empty($_POST['password'])) 
                { 
                    
    $password password_hash($_POST['password'], PASSWORD_BCRYPT, array("cost" => 10));  

                    
                } 
                else 
                { 
                    
    // If the user did not enter a new password we will not update their old one. 
                    
    $password null
                    
    $salt null
                } 

                
    // Initial query parameter values 
                
    $query_params = array( 
                    
    ':email' => $_POST['email'], 
                    
    ':user_id' => $_SESSION['user']['user_id'], 
                ); 

                
    // If the user is changing their password, then we need parameter values 
                // for the new password hash. 
                
    if($password !== null
                { 
                    
    $query_params[':password'] = $password
                } 

                
    // Note how this is only first half of the necessary update query.  We will dynamically 
                // construct the rest of it depending on whether or not the user is changing 
                // their password. 
                
    $query 
                    UPDATE users 
                    SET 
                        email = :email 
                "


                
    // If the user is changing their password, then we extend the SQL query 
                // to include the password column and parameter token too. 
                
    if($password !== null
                { 
                    
    $query .= 
                        , password = :password 
                    "

                } 

                
    // Finally we finish the update query by specifying that we only wish 
                // to update the one record with for the current user. 
                
    $query .= 
                    WHERE 
                        user_id = :user_id 
                "



                    
    // Execute the query 
                    
    $stmt $db->prepare($query); 
                    
    $result $stmt->execute($query_params); 



                
    // Now that the user's E-Mail address has changed, the data stored in the $_SESSION 
                // array is stale; we need to update it so that it is accurate. 
                
    $_SESSION['user']['email'] = $_POST['email']; 

                
    // This redirects the user back to the members-only page after they register 
                
    header("Location: private.php"); 

                
    // Calling die or exit after performing a redirect using the header function 
                // is critical.  The rest of your PHP script will continue to execute and 
                // will be sent to the user if you do not die or exit. 
                
    exit; 
            }
            else
            {
                echo 
    'invalid submission'
                
    trigger_error('possible CSRF attack'E_USER_ERROR);    // add details for logging like the user ID, the referrer (as a possible source of the attack) etc. 
                
    exit; 
            }
        } 
         
    ?> 
    <html>
        <body>
            <h1>Edit account</h1>
            <form action="edit_account.php" method="post"> 
                <input type="hidden" name="action_token" value="<?php echo html_escape($_SESSION['action_token']) ?>"> 
                Username:<br /> 
                    <b><?php echo html_escape($_SESSION['user']['username']); ?></b> 
                    <br /><br /> 
                E-Mail Address:<br /> 
                    <input type="text" name="email" value="<?php echo html_escape($_SESSION['user']['email']); ?>" /> 
                    <br /><br /> 
                Password:<br /> 
                    <input type="password" name="password" value="" /><br /> 
                    <i>(leave blank if you do not want to change your password)</i> 
                    <br /><br /> 
                    <input type="submit" value="Update Account" /> 
            </form>
        </body>
    <html>
    for the rest see post #7

    [[ "login with edit_acc.zip" removed in favor of "login 1.1.zip" 2014-07-01 --requinix ]]

    Comments on this post

    • Jacques1 agrees
    Attached Files
    Last edited by requinix; July 1st, 2014 at 02:46 PM. Reason: red note 2014-01-31; new attachment 2014-07-01
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Oct 2009
    Location
    Nebraska, USA
    Posts
    876
    Rep Power
    276
    um, where is this invisible code and zip-file posted?
  4. #3
  5. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    451
    Rep Power
    8
    wait some minutes, I'm working away the css to make the code more visible

    look again in 30 minutes or something then I should be ready to post the files
  6. #4
  7. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    451
    Rep Power
    8
    ok, the zip file is now in the main post, but with only that the system won't work. Also to activate the reCAPTCHA, follow this 'tutorial', and if you don't like following links, google 'recaptcha' and click the first link. Then 'use recaptcha on your site' and sign up. The rest will be explained. You'll need a code (private and public) to use the captcha.

    What you also need are some tables:

    Code:
    CREATE TABLE IF NOT EXISTS `responses` (
      `reset_key` char(32) COLLATE utf8_unicode_ci NOT NULL,
      `user` int(11) NOT NULL,
      `secret` char(60) COLLATE utf8_unicode_ci NOT NULL,
      `request_timestamp` datetime NOT NULL,
      `request_ip` varchar(39) COLLATE utf8_unicode_ci NOT NULL,
      `used` tinyint(1) NOT NULL DEFAULT '0',
      `active` tinyint(1) NOT NULL DEFAULT '1',
      PRIMARY KEY (`reset_key`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

    Code:
    CREATE TABLE IF NOT EXISTS `sent_emails` (
      `email_address` char(64) COLLATE utf8_unicode_ci NOT NULL,
      `timestamp` datetime NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

    Code:
    CREATE TABLE IF NOT EXISTS `unsubscribed_email_addresses` (
      `email_key` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
      `email_address` char(64) COLLATE utf8_unicode_ci DEFAULT NULL,
      `unsubscribed` tinyint(1) NOT NULL DEFAULT '0',
      PRIMARY KEY (`email_key`),
      UNIQUE KEY `email_address` (`email_address`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

    Code:
    CREATE TABLE IF NOT EXISTS `users` (
      `user_id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      `password` char(60) COLLATE utf8_unicode_ci NOT NULL,
      `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      `start_date` datetime NOT NULL,
      PRIMARY KEY (`user_id`),
      UNIQUE KEY `username` (`username`),
      UNIQUE KEY `email` (`email`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    Use these sql query's to create the tables that will make the login system work. I hope you'll find it usefull. If there are any problems, pm me or post it on this thread.
  8. #5
  9. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    451
    Rep Power
    8
    Oops, forgot the file edit_account.php, in this file the user will be able to change his/her password and/or email. This is the only change in the whole system but for goot measure, I upload the whole zip-file again with the edit_account.php

    I will remove the old zip-file and replace it with this one.
  10. #6
  11. Jealous Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,302
    Rep Power
    9400
    Would be nice if you could just include the code in the first post so we don't have to download anything...
    Also remember that the point of FAQ things is so that people don't have to scan through lots and lots of forum posts to get the information the need. The sooner you can show and explain the code, the better. In fact I'm much more likely to delete posts if they don't contribute towards the actual subject matter.
  12. #7
  13. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    451
    Rep Power
    8
    and continuing from the first post:

    forgot_password.php:

    PHP Code:
    <?php    

        
    require("common.php");    
        require(
    "lib/rnum.php");   
        require(
    "lib/mail.php");   
        require(
    "lib/password.php");    

        if(!empty(
    $_POST))    
        { 
            
    $submitted_email $_POST['email']; 
            
    ///// begin recaptcha 
            
    require_once('lib/recaptcha/recaptchalib.php'); 
            
    $privatekey ""
            
    $resp recaptcha_check_answer ($privatekey
              
    $_SERVER["REMOTE_ADDR"], 
              
    $_POST["recaptcha_challenge_field"], 
              
    $_POST["recaptcha_response_field"]); 

            if (!
    $resp->is_valid) { 
              
    // What happens when the CAPTCHA was entered incorrectly 
              
    die ("The reCAPTCHA wasn't entered correctly. Go back and try it again." 
                   
    "(reCAPTCHA said: " $resp->error ")"); //change this if you want to edit the page, for example: $msg = "Captcha wasn't entered correctly"; and display it later in the script 
            
    } else { 
            
    ///// end recaptcha 
                
    if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))    
                {       

                    
    $hash hash('sha256'$_POST['email']);   
                    
    $time = new DateTime('24 hours ago');    
                    
    $time_formatted $time->format('Y-m-d H:i:s');    

                    
    $count_stmt $db->prepare('     
                        SELECT COUNT(*)  as count   
                        FROM sent_emails   
                        WHERE email_address = :email_address AND timestamp >= :time    
                    '
    );    
                    
    $count_stmt->execute(array(     
                        
    ':email_address' => $hash,    
                        
    ':time' => $time_formatted     
                    
    ));     

                    
    $times $count_stmt->fetch();    
                    
    $email $_POST['email'];   
                    
    $user_stmt $db->prepare('    
                        SELECT    
                            user_id    
                        FROM    
                            users    
                        WHERE    
                            email = :email    
                    '
    );    
                    
    $user_stmt->execute(array(    
                        
    ':email' => $_POST['email']    
                    ));    
                    
    $user_id $user_stmt->fetchColumn();    
                    if(
    $user_id)  // is the mail of a user? 
                    
    {          
                        if(
    $times['count'] < 10)   
                        {   
                            
    $deactivation_stmt $db->prepare('    
                            UPDATE    
                                responses    
                            SET    
                                active = 0    
                            WHERE    
                                user = :user    
                            '
    );    
                            
    $deactivation_stmt->execute(array(    
                            
    ':user' => $user_id    
                            
    ));    

                            
    $password_token rnum();   

                            
    $query "    
                            INSERT INTO responses (    
                                reset_key,   
                                user,   
                                secret,   
                                request_timestamp,   
                                request_ip   
                            ) VALUES (    
                                :reset_key,   
                                :user,   
                                :secret,   
                                NOW(),   
                                :request_ip   
                            )"
    ;   

                            
    $secret password_hash($password_tokenPASSWORD_BCRYPT, array("cost" => 10));     
                            
    $reset_key rnum();     
                            
    $request_ip getenv('REMOTE_ADDR');   

                            
    $query_params = array(    
                                
    ':reset_key' => $reset_key,   
                                
    ':user' => $user_id,   
                                
    ':secret' => $secret,   
                                
    ':request_ip' => $request_ip   
                            
    );    

                            
    $stmt $db->prepare($query);    
                            
    $result $stmt->execute($query_params);                    

                            
    $mail_to      $email;   
                            
    $mail_subject 'Forgot password';   
                            
    $mail_body "Hallo,  
                                <br><br>  
                                you or somebody else requested a password reset for your user account at http://domain.com/.  
                                <br><br>  
                                To set a new password, please visit this link:  
                                <br><br>  
                                http://www.domain.com/password_reset.php?reset_key=" 
    $reset_key "&user=" $user_id "&password_token=" $password_token ."  
                                <br><br>  
                                Do not share the secret code in this link until you've used it. The code will expire in 30 minutes.   
                                <br><br>  
                                If the request was not from you, simply ignore this email. Your password will _not_ be changed.  
                                <br><br>  
                                Do you have further questions? Please contact us at info@domain.com.  
                                <br><br>  
                                Best regards,  
                                <br><br>  
                                domain.com"



                            if(
    mail_f ($mail_to$mail_subject$mail_body) == 1)   
                            {   
                                
    $new_stmt $db->prepare('     
                                INSERT INTO sent_emails (   
                                email_address,   
                                timestamp   
                                ) VALUES (   
                                :email_address,   
                                NOW()   
                                )'
    );    
                                
    $new_stmt->execute(array(     
                                
    ':email_address' => $hash           
                                
    ));          
                            }   
                        }   
                    }   
                    else{ 
    // is the mail not in the system  
                        
    if($times['count'] < 1)   
                        {   
                            
    $email_adress $_POST["email"];     
                            
    $hash hash('sha256'$email_adress);   
                            
    # the following is for an unregistered address that hasn't reached its request limit yet   

                            # you only need one query   
                            
    $unsub_data_stmt $db->prepare('     
                                SELECT    
                                    unsubscribed   
                                    , email_key   
                                FROM    
                                    unsubscribed_email_addresses    
                                WHERE   
                                    email_address = :hash   
                            '
    );   
                            
    $unsub_data_stmt->execute(array(     
                                
    ':hash' => $hash    
                            
    ));     
                            
    $unsub_data $unsub_data_stmt->fetchColumn();   

                            
    // If we don't have a record of the address yet, or if the address isn't unsubscribed,   
                            // send an email; in case of a new record, generate a new token, otherwise, use the old one;   
                            // $valid_token determines whether the newly generated token has been stored and can actually   
                            // be used; if not, it shouldn't be in the mail   
                            
    $send_mail $valid_token false;   
                            if ( 
    $unsub_data === false )   
                            {   
                                
    $send_mail true;   
                                
    $unsub_token rnum();   
                                
    $unsubscribe_stmt $db->prepare('     
                                    INSERT INTO unsubscribed_email_addresses (     
                                        email_address   
                                        , email_key   
                                    ) VALUES (     
                                        :email_key   
                                        , :email_address    
                                    )  
                                '
    );     
                                
    $valid_token $unsubscribe_stmt->execute(array(   
                                    
    ':email_address' => $hash   
                                    
    ':email_key' => $unsub_token   
                                
    ));   
                            }   
                            elseif ( !
    $unsub_data['unsubscribed'] )   
                            {   
                                
    $send_mail $valid_token true;   
                                
    $unsub_token $unsub_data['email_key'];   
                            }   

                            if ( 
    $send_mail )   
                            {   
                                
    $email_adress $_POST["email"];  
                                
    $mail_subject "Forgot password";  
                                
    $mail_body "Hallo,  
                                    <br><br>  
                                    you or somebody else entered your email address into the password reset form at http://domain.com, but your address is not registered in our system.  
                                    <br><br>  
                                    If you have an account on our website, you must have used a different email address. Please try again with your other addresses.  
                                    <br><br>  
                                    If you did not use our form, we apologize for this email. Please ignore it. If you never want to receive the email again, you can mark your address as blocked in our system:  
                                    <br><br>  
                                    http://www.domain.com/no_mail.php?email_key=" 
    $unsub_token "  
                                    <br><br>  
                                    Do you have further questions? Please contact us at info@domain.com.  
                                    <br><br>  
                                    Best regards,  
                                    <br><br>  
                                    domain.com"
    ;   

                                
    # put the mail text into an external template; only append the token if $valid_token   
                                
    if( mail_f($email_adress$mail_subject$mail_body) )    
                                {    
                                    
    $sent_stmt $db->prepare('      
                                        INSERT INTO sent_emails (   
                                            email_address    
                                            , timestamp    
                                        ) VALUES (    
                                            :email_address   
                                            , NOW()    
                                        )   
                                    '
    );     
                                    
    $sent_stmt->execute(array(      
                                        
    ':email_address' => $hash            
                                    
    ));   
                                }   
                            }  
                        }   
                    }   
                    echo 
    "Unless your limit has been reached, we'll send you an email";  
                }   
                else{   
                    echo 
    "This emailadress is invalid!";   
                }   
            } 
        }   
    ?> <html> 
        <body> 
            <h1>Forgot password</h1> 
            <form action="forgot_password.php" method="post">    
                Email:   
                <input type="text" name="email" value="<?php echo $submitted_email?>" />    
                <br /><br />    
                <?php 
                    
    require_once('lib/recaptcha/recaptchalib.php'); 
                    
    $publickey ""// you got this from the signup page 
                    
    echo recaptcha_get_html($publickey); 
                
    ?> 
                <input type="submit" value="Recover" />    
            </form>   
        </body> 
    </html>
    [[ modified at derplumo's request 2014-07-01 --requinix ]]

    login.php:

    PHP Code:
    <?php 
        
    ///////////////////////////////////////////
        ///////////////////////////////////////////
        ///* This is a login system, used to secure private (members-only) pages for a website 
        ///* Created by Ricardo van der Pluijm (derplumo on Devshed)
        ///* Based on the files located on: 
        ///*    http://forums.devshed.com/php-faqs-and-stickies-167/how-to-program-a-basic-but-secure-login-system-using-891201.html
        ///*    By E-Oreo
        ///*
        ///* The login files are located at:
        ///*    http://forums.devshed.com/php-faqs-and-stickies-167/a-more-advanced-login-system-with-password-forgot-955871.html
        ///*
        ///*
        ///* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        ///* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        ///* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        ///* THE SOFTWARE.
        /////////////////////////////////////////////
        /////////////////////////////////////////////

        
    require("common.php"); 
        require(
    "lib/password.php"); 
        require (
    "lib/functions.php");
        
        
    $submitted_username ''


        if(!empty(
    $_POST)) 
        { 
            
    $user_information_stmt $db->prepare(
                SELECT 
                    user_id, 
                    username, 
                    password, 
                    email 
                FROM users 
                WHERE 
                    username = :username 
            '
    ); 


            
    $user_information_stmt->execute(array( 
                
    ':username' => $_POST['username'
            )); 

            
    $login_ok false

            
    $row $user_information_stmt->fetch(); 
            if(
    $row
            { 
                if ( 
    password_verify($_POST['password'], $row['password']) )    
                {  
                    
    $login_ok true;  
                }  
            } 

            if(
    $login_ok
            { 
                unset(
    $row['password']); 
                
    $_SESSION['user'] = $row
                
    $_SESSION['action_token'] = generate_secure_token(); 

                
    header("Location: private.php"); 
                exit; 
            } 
            else 
            { 
                print(
    "Login Failed."); 
                
    $submitted_username html_escape($_POST['username']); 
            } 
        } 

    ?> 
    <html>
        <body>            
            <h1>Login</h1>
            <form action="login.php" method="post"> 
            Username: 
                <input type="text" name="username" value="<?php echo $submitted_username?>" /> 
                <br /><br /> 
            Password:
                <input type="password" name="password" value="" /> 
                <br /><br /> 
            <input type="submit" value="Login" /> 
            </form> 
            <a href="register.php">Register</a>
        </body>
    </html>
    logout.php:
    PHP Code:
    <?php 

        
    // First we execute our common code to connection to the database and start the session 
        
    require("common.php"); 
         
        
    // We remove the user's data from the session 
        
    unset($_SESSION['user']); 
        unset(
    $_SESSION['action_token']);
        
        
    // We redirect them to the login page 
        
    header("Location: login.php"); 
        exit;
    no_mail.php:
    PHP Code:
    <?php 

    require("common.php"); 


    if( !empty(
    $_GET['email_key']) ) 

        
    $key_stmt $db->prepare(
            SELECT 
                unsubscribed 
            FROM 
                unsubscribed_email_addresses 
            WHERE 
                email_key = :email_key 
        '
    ); 
        
    $key_stmt->execute(array( 
            
    ':email_key' => $_GET['email_key'
        )); 
        
    $unsub $key_stmt->fetchColumn(); 
        if ( 
    $unsub === false )            // key doesn't exist 
            
    echo 'Invalid email key. Please check the URL in your previous notification email.'
        else                            
    // key exists 
        

            if ( !
    $unsub )                // not unsubscribed yet 
            

                
    $unsub_stmt $db->prepare(
                    UPDATE 
                        unsubscribed_email_addresses 
                    SET 
                        unsubscribed = 1 
                    WHERE 
                        email_key = :email_key 
                '
    ); 
                
    $unsub_stmt->execute(array( 
                    
    ':email_key' => $_GET['email_key'
                )); 
                if ( 
    $unsub_stmt->rowCount() ) 
                    
    $unsub true
            } 
            if ( 
    $unsub 
                echo 
    'Your email address has been blocked in our system. You will no longer receive notification emails.'
            else 
                echo 
    'There was a technical issue. Please try again later.'
        } 

    else 
        echo 
    'Missing email key. Please check the URL in your previous notification email. It must have the form http://domain.com/no_mail.php?email_key=...';
    password_reset.php:
    PHP Code:
    <?php   
        
    require("common.php");   
        require(
    "lib/password.php");  

        
    $reset_key $_GET["reset_key"];  
        
    $user $_GET["user"];  
        
    $password_token $_GET["password_token"];  
          

        if(!empty(
    $_POST))   
        {   
            
    $reset_echo true;
            
    $reset_successful false
            
    $reset_key $_POST['reset_key'];  
            
    $user $_POST['user'];  
            
    $password_token $_POST['password_token'];  

            
    $response_stmt $db->prepare('  
                SELECT   
                    user  
                    , secret 
                    , request_timestamp 
                FROM 
                    responses  
                WHERE   
                    reset_key = :reset_key 
                    AND user = :user 
                    AND NOT used 
                    AND active 
                '
    ); 
               
            
    $response_stmt->execute(array(   
                
    ':reset_key' => $reset_key
                
    ':user' => $user  
            
    ));  
              
            
    $response $response_stmt->fetch();   

            if(
    $response)  
            {              
                
    $created DateTime::createFromFormat('Y-m-d G:i:s'$response['request_timestamp']);   
                if ( 
    $created >= new DateTime('30 minutes ago') )   
                {  
                    if ( 
    password_verify($password_token$response['secret']) )  
                    {  
                        
    //disable used token
                        
                        
    $disable_token_stmt $db->prepare('
                            UPDATE responses
                            SET
                                used = :used
                            WHERE   
                                reset_key = :reset_key 
                                AND user = :user 
                        '
    );
                        
    $disable_token_stmt->execute(array(   
                            
    ':used' => '1'
                            
    ,':reset_key' => $reset_key
                            
    ,':user' => $user  
                        
    ));  
                        
                        
    //change the password
                        
    $password_change_stmt $db->prepare('   
                            UPDATE users   
                            SET   
                                password = :password  
                            WHERE  
                                user_id = :user_id   
                            '
    );   

                        
    $hash password_hash($_POST['password'], PASSWORD_BCRYPT, array("cost" => 10));           

                        
    $password_change_stmt->execute(array(   
                            
    ':password' => $hash,   
                            
    ':user_id' => $response['user']  
                        ));   
                    
                        
    $reset_successful true
                    }   
                }                       
            }          
        }  
    ?> <html>
        <body>            
            <h1>Forgot password</h1>
            <?php  
                
    if ($reset_echo) {
                    if (
    $reset_successful
                        echo 
    'Your password has been reset!'
                    else
                        echo 
    'This token has already been used, expired or inactive, please request a new one';  
                }
            
    ?>
            <form action="password_reset.php" method="post">    
                New password:  
                    <input type="text" name="password" value="" />   
                    <br /><br />   
                <input type="hidden" name="reset_key" value="<?php echo $reset_key?>" />  
                <input type="hidden" name="user" value="<?php echo $user?>" />  
                <input type="hidden" name="password_token" value="<?php echo $password_token?>" />  
                <input type="submit" value="Login" />   
            </form> 
        </body>
    </html>
    private.php:
    PHP Code:
    <?php 

        
    require("common.php"); 
         
        if(empty(
    $_SESSION['user'])) 
        { 
            
    header("Location: login.php"); 
            exit; 
        } 
    ?> 
    login succeded, congrats!
    <br><br>
    From here on the files beginning with this code:

    require("common.php"); 

    if(empty($_SESSION['user'])) 

        header("Location: login.php"); 
        exit; 


    will be protected by the script, note this piece of code has to be on EVERY page you want to protect. This code is also visable in the file 'private.php'
    register.php:
    PHP Code:
    <?php 
        
        
    require("common.php"); 
        require(
    "lib/password.php");
        require(
    'lib/functions.php');
        
    $submitted_username "";
        
    $submitted_email "";
        
        if(!empty(
    $_POST)) 
        {    
            
    //// recaptcha
            
    require_once('lib/recaptcha/recaptchalib.php');
            
    $privatekey "";
            
    $resp recaptcha_check_answer ($privatekey,
              
    $_SERVER["REMOTE_ADDR"],
              
    $_POST["recaptcha_challenge_field"],
              
    $_POST["recaptcha_response_field"]);

            if (!
    $resp->is_valid) {
              
    // What happens when the CAPTCHA was entered incorrectly
              
    die ("The reCAPTCHA wasn't entered correctly. Go back and try it again." .
                   
    "(reCAPTCHA said: " $resp->error ")");
            } else {
              
    // Your code here to handle a successful verification
            
            
            //// end recaptcha
                
    if(!empty($_POST['username'])) 
                {         
                    
    $submitted_username $_POST['username'];                   // is there has been filled in something, not regarding the password, then we'll have to place that back into the form, so that the user doesn't have to fill in all the data again.
                    
    if(filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
                    {
                        
    $submitted_email $_POST['email'];
                    }
                    if(!empty(
    $_POST['password'])) 
                    { 
                        if(
    filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) 
                        { 
                            
    $submitted_email $_POST['email'];
                            
    $user_exist_stmt $db->prepare('  
                                SELECT 
                                    1 
                                FROM users 
                                WHERE 
                                    username = :username 
                            '
    ); 


                            
    $user_exist_stmt->execute(array( 
                                
    ':username' => $_POST['username'
                            )); 

                            
    $user_exist $user_exist_stmt->fetch(); 

                            if(!
    $user_exist
                            { 
                                
    $email_exist_stmt $db->prepare(
                                    SELECT 
                                        1 
                                    FROM users 
                                    WHERE 
                                        email = :email 
                                '
    ); 

                                
    $email_exist_stmt->execute(array( 
                                    
    ':email' => $_POST['email'
                                )); 

                                
    $email_exist $email_exist_stmt->fetch(); 

                                if(!
    $email_exist
                                { 

                                    
    $register_stmt $db->prepare(
                                    INSERT INTO users ( 
                                        username, 
                                        password, 
                                        email, 
                                        start_date
                                    ) VALUES ( 
                                        :username, 
                                        :password, 
                                        :email,
                                        NOW()
                                    )'
    ); 
                                    
    $hash password_hash($_POST['password'], PASSWORD_BCRYPT, array("cost" => 10));  

                                    
    $register_stmt->execute(array( 
                                        
    ':username' => $_POST['username'], 
                                        
    ':password' => $hash
                                        
    ':email' => $_POST['email']
                                    )); 

                                    
    header("Location: login.php"); 
                                    exit; 
                                }
                                else {
                                    
    $message "This email address is already registered";
                                }
                            }
                            else {
                                
    $message "This username is already in use";
                            }
                        }
                        else {
                            
    $message "Invalid E-Mail Address"
                        }
                    }
                    else {
                        
    $message "Please enter a password."
                    }
                }
                else {
                    
    $message "Please enter a username.";
                }
            }
        } 

    ?> 

    <html>
        <body>
            <h1>Register</h1>
            <?php echo $message?>
            <form action="register.php" method="post"> 
                Username:
                    <input type="text" name="username" value="<?php echo html_escape($submitted_username);?>" /> 
                <br /><br /> 
                E-Mail:
                    <input type="text" name="email" value="<?php echo html_escape($submitted_email);?>" /> 
                <br /><br /> 
                Password: 
                    <input type="password" name="password" value="" /> 
                <br /><br /> 
                <?php
                    
    require_once('lib/recaptcha/recaptchalib.php');
                    
    $publickey ""// you got this from the signup page
                    
    echo recaptcha_get_html($publickey);
                
    ?>
                <input type="submit" value="Register" /> 
            </form>
        </body>
    </html>

    Comments on this post

    • Jacques1 agrees : Excellent job. And thanks for making the code available to everybody.
    Last edited by requinix; July 1st, 2014 at 02:30 PM.
  14. #8
  15. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    451
    Rep Power
    8
    NOTE that you need access to /dev/urandom! Otherwise your hashing library won't work or it will use a very weak number that should be secure.

    (I put the note here because I couldn't edit the first post anymore)

    Comments on this post

    • requinix agrees : if you ever want to make more changes, IM me and I'll get them in for you
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2014
    Posts
    44
    Rep Power
    1
    Originally Posted by derplumo
    NOTE that you need access to /dev/urandom! Otherwise your hashing library won't work or it will use a very weak number that should be secure.

    (I put the note here because I couldn't edit the first post anymore)
    Hi Guys,
    Firstly, I'd like to thank all the contributors for their fine piece of work in developing a secured script for others to develop their knowledge on the subject. Great work!
    I am a PHP and MYSQL newbie... I've installed the scripts that are on the first page of this thread and it's fully functional.
    Now I jammed up with this thread and noticed that these scripts are totally different from the ones on the front page. I wonder which ones are the last updated versions.
    Please advise

    Thanks in advance...
  18. #10
  19. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    451
    Rep Power
    8
    Originally Posted by netfreak
    Now I jammed up with this thread and noticed that these scripts are totally different from the ones on the front page.
    Hi netfreak,

    What do you exactly mean with 'front page' and 'these scripts'? If you mean the thread How to program a basic but secure login system using PHP and MySQL yes, the scripts on this page are the most recent version.

    The other thread was (I believe) intended to learn the new scripters how to program a basic but secure login system. I worked out a new version with an other very well known user on this site and you could try to put everything together from that thread, but I posted the newest version here.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2014
    Posts
    44
    Rep Power
    1
    Hi Derplumo,

    Thanks for your prompt response and sorry for not being clear. Yes, I meant the beginning of the thread.
    I've just downloaded the zip file on this current page and I will give it a shot.
    I'll surely let you know how it goes.
    I am a very slow learner and it will take some time.


    Thanks again.
  22. #12
  23. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    451
    Rep Power
    8
    Sure,

    good luck, and let me know if you run into a problem
    Last edited by derplumo; March 1st, 2014 at 06:16 PM.
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2014
    Posts
    44
    Rep Power
    1
    [QUOTE=... and let me know if you run into a problem [/QUOTE]

    I did a fresh install with all the zipped files and the sql tables on this page.
    I didn't want to register with Google to use recaptcha (with all respect for your security input), so for now, I commented that chunk of code in register.php and I tried to register.
    Results:
    All input data enters the users table in the database EXCEPT the password. I wonder if this has anything to do with commenting the recaptcha?

    Thanks.
  26. #14
  27. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    451
    Rep Power
    8
    It works here, could you post the chunk of code you edited please?
    Last edited by derplumo; March 1st, 2014 at 07:11 PM.
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2014
    Posts
    44
    Rep Power
    1
    Originally Posted by derplumo
    It works here, could you post the chunk of code you edited please?

    Code:
    /*
     //// recaptcha
            require_once('lib/recaptcha/recaptchalib.php');
            $privatekey = "";
            $resp = recaptcha_check_answer ($privatekey,
              $_SERVER["REMOTE_ADDR"],
              $_POST["recaptcha_challenge_field"],
              $_POST["recaptcha_response_field"]);
     
            if (!$resp->is_valid) {
              // What happens when the CAPTCHA was entered incorrectly
              die ("The reCAPTCHA wasn't entered correctly. Go back and try it again." .
                   "(reCAPTCHA said: " . $resp->error . ")");
            } else {
              // Your code here to handle a successful verification
     
     
            //// end recaptcha
     
    */
     
    		// } // commented 	  
     
    				 <?php
                    require_once('lib/recaptcha/recaptchalib.php');
                    $publickey = ""; // you got this from the signup page
                    echo recaptcha_get_html($publickey);
                ?>
Page 1 of 10 123 ... Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo