paint-brush
Mastering the PHP GD Library - Part 3: Building a Captchaby@emmykolic1
166 reads

Mastering the PHP GD Library - Part 3: Building a Captcha

by Emmanuel Okolie August 20th, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Learn to implement a captcha using PHP GD Library. Prevent spam and unauthorized access. Use random codes and incorporate captcha into a contact form for enhanced security. This tutorial guides you step by step, offering code snippets and explanations. Create and validate captchas effectively for improved web application security.

People Mentioned

Mention Thumbnail
featured image - Mastering the PHP GD Library - Part 3: Building a Captcha
Emmanuel Okolie  HackerNoon profile picture

As software development continues to evolve, the need for a captcha is essential. What a captcha does is that it prevents a robot from trying to submit a form on your site.


Our last tutorial discussed, how to generate your watermark Image using PHP GD Library. This is going to be the last tutorial on PHP GD Library from Emmykolic. Note, there are quite a few things you can do with PHP GD.


But, so far, we have looked at three things we can use the GD library for. If this is the first tutorial on the GD library you’re reading, I’ll advise you to look at our Blog, there you will find all the examples we used the GD library in PHP to create.


Now, we'll talk about how to build a captcha with PHP GD Library.


If you want to view the source code of this project, kindly visit my Github_Repository, where you will see everything concerning the captcha using the GD library. After working with the Repository Please do well to Follow me on GitHub. Thanks!


Without wasting much of your time let's jump into this tutorial.


Content Overview

  • Prerequisites
  • What You Should Know About Captcha
  • PHP Captcha With Registration Form Using GD Library
  • Connect The Captcha To a Registration Form
  • Conclusion


Prerequisites

  1. A code Editor(VS Code or Sublime Text)

  2. Please make sure that GD(Graphics Draw) library is installed on your host. Most web hosts already have it. But if you don’t then you can install it, follow the instructions.


What You Should Know About Captcha

We'll cover how to make a captcha using the GD library. We'll also look at PHP server-side captcha validation. Finally, we'll learn how to incorporate Captcha into a contact form.

On the Internet, scammers and hackers exist, and they create hazardous applications to gain access to your application. You might have a lot of trouble because of XSS attacks, SQL injection, and mass spam mailings.


Spam can increase server load and cause your online application to go down, which makes it unavailable. Customers or site users are immediately impacted. It affects your internet business as a result.


One of the greatest remedies for this affliction is a captcha. It guards against unauthorized access and spam bots. It stops bots from submitting pointless information through the PHP contact form. A randomly generated code is used in the CAPTCHA. Run-time production takes place. It appears in a variety of shapes. Here are some examples of popular Captcha types:

Audio, Graphical (Image), and Text The user must enter the random number that makes up the captcha code. Validation ensures that a genuine human entered the value; in essence, a bot has difficulty filling out the captcha code. In this manner, spam is avoided.


PHP Captcha With Registration Form Using GD Library

Let's now focus on a simple example of implementing a PHP CAPTCHA script. I've designed this project to illustrate how to use a CAPTCHA to prevent spam.


To understand our approach to using the PHP CAPTCHA script effectively, take a look at the project structure outlined below.


We start by setting up a CAPTCHA field. After filling in this CAPTCHA field and submitting it, users will be directed to a basic contact form where they can provide their name, gender, and email. It's important to complete the CAPTCHA test before accessing the main registration form; the CAPTCHA test is mandatory. Once a user submits the registration form, a success message will appear at the top. Here's an overview of the project structure we'll be working with.


\--How_to_build_a_simple_captcha_with_PHP_GD
  |-- css
    |-- style.css
  |--- fonts
    |-- Monofont.ttf
  |-- js
  |--- captcha.php
  |--- config.php
  |-- footer.php
  |--- form.php
  |--- header.php
  |-- index.php
  |-- register_action.php



HTML Contact Form with Captcha

The contact form has a file called header.php. so create a file call it header.php, the header.php file contains the HTML Doctype declaration and a set of link tags. The header page is a continuation of the index page I separated the full index page into three pieces the header, index, and footer. Then, I included them in the index page using the php include the statement.


Below is the code snippet for header.php:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="css/bootstrap.min.css" rel="stylesheet" >
    <link rel="stylesheet" href="css/owl.carousel.min.css">
    <link rel="stylesheet" href="css/owl.theme.default.min.css">
    <link rel="stylesheet" type="text/css" href="css/aos.css">
    <link rel="stylesheet" type="text/css" href="css/fontawesome/css/all.min.css">
    <link rel="stylesheet" href="css/style.css">
    <title><?='Captcha' ?></title>
</head>
<body>


Also, the contact form has a file called footer.php So, create a file call it footer.php, the footer.php file contains the closing of the body and HTML tag and some set of script tags.


Below is the code snippet for footer.php

<script src="js/bootstrap.bundle.min.js" ></script>
    <script src="Js/jquery.min.js"></script>
    <script src="js/owl.carousel.min.js"></script>
    <script src="js/aos.js"></script>
    <script src="js/script.js"></script>
</body>
</html>


The first page you will see when you open the project in your local host is the Index.php page, which is the captcha page that performs captcha validation before taking you to the registration page.


Below is the code snippet for the index.php.

<?php include 'header.php'; ?>
	<div class="container">
		  <div class="row">
		     <div class="col-md-6 offset-md-3 mt-4 shadow">
			      <form method="POST" class="bg-white p-5" action="form.php">
              <h2>PROVE! YOU ARE NOT A ROBOT!!</h2><hr>
              <strong class="alert alert-danger text-muted pt-2">
                Type the text in the image to prove
                you are not a robot
              </strong>
              <img style="display: block; margin: 10%;" src="captcha.php" alt="image verification" />
              <input type="text" id="captchha" name="captcha" size="20" maxlength="6" class="form-control m-1">
              <input type="submit" value="Submit" class="btn btn-success col-12 m-1">
                <?php
                /*if captcha code is posted*/
                if(isset($_POST["captcha"]))					
                  if($_SESSION["captcha"]==strtolower($_POST["captcha"])):/*CAPTCHA is valid. You can process the form now.*/?>
                  <p class="text-success"> CAPTCHA is valid. You can process the form now.</p>
                <?php else: /*Invalid CAPTCHA*/ ?>
                  <p class="text-danger">Invalid <strong>CAPTCHA.</strong> Pls Try again!</p>
                <?php endif; ?>
                <div>
                  Can't read the image? Click
                  <a style="text-decoration: none" href='<?= $_SERVER['PHP_SELF']; ?>'>
                    <i class="fa fa-sync"></i>
                  </a>
                  to refresh!
		            </div>
		        </form>
		     </div>
	    </div>
	</div>
<?php include 'footer.php'; ?>


After writing the above code snippet, you will have to perform some styling, even though I used Bootstrap v5 for the structure and the layout of the entire interface of the project. We also styled some tags and declared a variable in CSS.


Below is the CSS Code Snippet for the styling:

:root {
--blue: #1e90ff;
--white: #ffffff;
--fbold:  bold;
}

body { background-color: var(--blue); display:flex; flex-direction:column; align-items: center; justify-content: center; }
h2 { border-bottom: 2px solid var(--white);}
p{ font-weight: var(--fbold);}


Creating The Captcha Page

Now, Create a new file and call it captcha.php. The captcha page will be linked to the index.php file created earlier. Every code we will be writing on the captcha page will be related to an image tag like the snippet you see below.

<img style="display: block; margin: 10%;" src="captcha.php" alt="image verification" />


In the image tag, we wrote an inline CSS that made our captcha to be positioned in the way it is. We used src='' to link to the captcha.php page, meaning that whatever is in the captcha page will be displayed as an image. The code below should be pasted in your captcha.php file. Looking at the code carefully, you will notice how we got the captcha numbers.


We are generating random numbers using the md5() function, what this means is that we are getting different numbers with the function. Note, we can’t get the same set of numbers twice. Note that the MD5 algorithm is widely used because it is relatively fast and produces a relatively unique hash.


Just look at the code snippet carefully you will understand what we did there.


Paste the code snippet below in the captcha.php file.

<?php
session_start();

/*Create a 220x35 image*/
$im = imagecreatetruecolor(220, 35);

/*Color code for orange*/
$orange = imagecolorallocate($im, 0xFF, 0x8c, 0x00);

/*Color code for white*/
$white = imagecolorallocate($im, 0xFF, 0xFF, 0xFF);

/*Generate a random string using md5*/
$md5_hash = md5(rand(0,999));

/*Trim the string down to 6 characters*/
$captcha_code = substr($md5_hash, 15, 6);

//Store the value of the generated captcha code in session
$_SESSION['captcha'] = $captcha_code;

/* Set the background as orange */
imagefilledrectangle($im, 0, 0, 220, 35, $orange);

/*Path where TTF font file is present*/
$font_file = getcwd() . '/fonts/Pixelation.ttf';

/* Draw our randomly generated code*/
imagefttext($im, 30, 0, 5, 30, $white, $font_file, $captcha_code);

/* Output the image to the browser*/
header('Content-Type: image/png');
imagepng($im);

/*Destroy*/
imagedestroy($im);
?>


After running the above snippet, the Interface below is what you will see on the index.php page on your browser.

The View Of The Index Page When You’re Done With Everything.


Connect The Captcha To a Registration Form

After running the captcha, if it’s not successful, it remains on the captcha page for you to try again, but if it’s successful it will take you to a page where you can register.


Now, you will create a page called form.php and create another page called config.php the config will be the page that contains the database connection, below is the code snippet for the config page.

<?php
session_start();
$db=new mysqli("localhost", "root", "", "gd_test");
Define("SITE_NAME", "Rights.com");
Define("SITE_SLUG", "Taking action on abuse");
function get_post($index){
	$index=$_POST[$index];
	return $index;
}

function set_alert($msg, $alert_type="danger"){
	$_SESSION['msg']=$msg;
	$_SESSION['alert_type']=$alert_type;
}

function get_alert(){
	if(isset($_SESSION['msg']) && $_SESSION['msg']!=""){
		?>
			<div class="alert alert-<?=$_SESSION['alert_type']?>"><?=$_SESSION['msg']?></div>
		<?php
	}
	$_SESSION['msg']="";
	$_SESSION['alert_type']="";
}
?>


When using your form.php you will include the config.php first then you will include the header.php before writing the code for building the form.


Below is the snippet for the form.php you created.

<?php 
include 'config.php';
include 'header.php';
?>
	<div class="container">
		<div class="row">
			<div class="col-md-6 offset-md-3 mt-5 shadow">
				<form method="post" class="bg-white p-5" action="register_action.php">
					<div class="bg-success text-center text-white fbold fs-6"><?= get_alert()?></div>
				<?php
					/*if captcha code is posted*/
					if(isset($_POST["captcha"]))					
						if($_SESSION["captcha"]==strtolower($_POST["captcha"])):/*CAPTCHA is valid. You can process the form now.*/?>
							<div class=" bg-success text-center p-2  text-white fw-bold fs-6"> CAPTCHA is valid. You can process the form now.</div>
						<?php else: /*Invalid CAPTCHA*/ 
								header("location: index.php");
							?>
							<p class="text-danger">Invalid <strong>CAPTCHA.</strong> Pls Try again!</p>
						<?php endif; ?>
						<h2 class="mt-2">Registration</h2>
						<div class="mb-3">
							<label>Fullname <span class="text-danger">*</span></label>
							<input type="text" id="captchha" name="fullname" size="20" class="form-control m-1">			
						</div>
						<div class="mb-3">
							<label>Gender <span class="text-danger">*</span></label>
							<input type="text" id="captchha" name="gender" size="20" class="form-control m-1">			
						</div>
						<div class="mb-3">
							<label>Email <span class="text-danger">*</span></label>
							<input type="email" id="captchha" name="email" size="20" class="form-control m-1">			
						</div>
						<div class="mb-3">
							<input type="submit" name="submit" value="Submit" class="btn btn-success col-12 m-1">
						</div>
				</form>
			</div>
		</div>
	</div>
	<?php include 'footer.php'; ?>


Note: You have to include the header and footer so that the form will have a good desktop and responsive view. If you follow the code, the interface below is what you will see in your browser.


After your captcha has been checked, here is the next page you will see


Note, this form you just created has an action page, that enables the PHP validation process in the database. Create a new file and call it register_action.php then write the code snippet below inside of the register_action.php


Below is the action page of the form.php.

<?php 
	include 'config.php';
	$error = 0;
	$error_msg="";
	if (isset($_POST['submit'])) {
		$fullname = get_post("fullname");
		$gender = get_post("gender");
		$email = get_post("email");
		if ($fullname == "") {
			$error = 1;
			$error_msg.="fullname is Empty";
		}
		if ($gender == "") {
			$error = 1;
			$error_msg.="gender is Empty";
		}
		if ($email == "") {
			$error = 1;
			$error_msg.="email is Empty";
		}

		$check=$db->query("SELECT * FROM users WHERE email='$email' OR fullname='$fullname'");
        if($check->num_rows>0){
            $error=1;
            $error_msg.="your Email or Fullname is already in use <br>"; 
        }
	}

	if($error==0){
    	$db->query("INSERT INTO users(fullname, gender, email) VALUES('$fullname','gender', '$email')");
    	set_alert("success", "your registration was successful");
	   	header("location:form.php");
	}else{
	    set_alert("danger", $error_msg);
	    header("location:index.php");
	}

?>


In the register_action.php page, we selected the values in the name attribute in our form.php page, saved them in a variable similar to their names, and did some validation process that enables proper validation.


Now fill in the fields of the registration form and submit it, it will show success in a green background. But if it’s not successful it will take you to the captcha page to start afresh, like the interface below shows success because the validation was successful.


After Submitting the form Here’s what you will see


Conclusion

We’ve come to the end of this tutorial. Hopefully, you gained a ton of value.

If you’ve followed this GD library series, you can now generate watermark images, build a captcha, and more. We also did a level of form validation.


If you enjoyed this series, like and drop a comment!!


Till next time, have a wonderful day!


Also published here.