Login and Registration using PHP and RESTful API
Hello everyone ! In this tutorial, you will learn how to create a Login and Registration RESTful API using PHP and MySQL Database.
Prerequisites
• Knowledge about basic web framework(HTML,CSS,Javascript).
• Familiarity with Python programming language.
• XAMPP
• PHP
• MySQL
Tutorial Begins
Follow the steps written below:
Step 1 : MySQL Database Setup
First, we will set up the MySQL Database for this application.
Table Name – users
Go inside your MySQL Database and create a new Database called php_auth_api. After that, use the following SQL code to create the users table and the structure of this table –
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Step 2 : Creating files & folders
First, Open your Xampp htdocs dir or your server www dir, and here create a new folder called php-auth-api. This is our application folder. After that, you need to install JWT inside this folder, as we will be using it for authorization.
Now we need to create the folders and files as given in the following image of the php-auth-api folder structure.
Inside the application folder, you need to create a new folder called classes, and inside the classes folder, we will create two files or classes –
Database.php – For making the database connection.
JwtHandler.php – For handling the JWT actions like encoding and decoding token.
class Database{
// CHANGE THE DB INFO ACCORDING TO YOUR DATABASE
private $db_host = 'localhost';
private $db_name = 'php_auth_api';
private $db_username = 'root';
private $db_password = '';
public function dbConnection(){
try{
$conn = new PDO('mysql:host='.$this->db_host.';dbname='.$this->db_name,$this->db_username,$this->db_password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
}
catch(PDOException $e){
echo "Connection error ".$e->getMessage();
exit;
}
}
}
Also add this
require './vendor/autoload.php';
use Firebase\JWT\JWT;
class JwtHandler
{
protected $jwt_secrect;
protected $token;
protected $issuedAt;
protected $expire;
protected $jwt;
public function __construct()
{
// set your default time-zone
date_default_timezone_set('Asia/Kolkata');
$this->issuedAt = time();
// Token Validity (3600 second = 1hr)
$this->expire = $this->issuedAt + 3600;
// Set your secret or signature
$this->jwt_secrect = "this_is_my_secrect";
}
public function jwtEncodeData($iss, $data)
{
$this->token = array(
//Adding the identifier to the token (who issue the token)
"iss" => $iss,
"aud" => $iss,
// Adding the current timestamp to the token, for identifying that when the token was issued.
"iat" => $this->issuedAt,
// Token expiration
"exp" => $this->expire,
// Payload
"data" => $data
);
$this->jwt = JWT::encode($this->token, $this->jwt_secrect, 'HS256');
return $this->jwt;
}
public function jwtDecodeData($jwt_token)
{
try {
$decode = JWT::decode($jwt_token, $this->jwt_secrect, array('HS256'));
return [
"data" => $decode->data
];
} catch (Exception $e) {
return [
"message" => $e->getMessage()
];
}
}
}
Create AuthMiddleware.php This file is for checking whether the token is valid or not.
require __DIR__ . '/classes/JwtHandler.php';
class Auth extends JwtHandler
{
protected $db;
protected $headers;
protected $token;
public function __construct($db, $headers)
{
parent::__construct();
$this->db = $db;
$this->headers = $headers;
}
public function isValid()
{
if (array_key_exists('Authorization', $this->headers) && preg_match('/Bearer\s(\S+)/', $this->headers['Authorization'], $matches)) {
$data = $this->jwtDecodeData($matches[1]);
if (
isset($data['data']->user_id) &&
$user = $this->fetchUser($data['data']->user_id)
) :
return [
"success" => 1,
"user" => $user
];
else :
return [
"success" => 0,
"message" => $data['message'],
];
endif;
} else {
return [
"success" => 0,
"message" => "Token not found in request"
];
}
}
protected function fetchUser($user_id)
{
try {
$fetch_user_by_id = "SELECT `name`,`email` FROM `users` WHERE `id`=:id";
$query_stmt = $this->db->prepare($fetch_user_by_id);
$query_stmt->bindValue(':id', $user_id, PDO::PARAM_INT);
$query_stmt->execute();
if ($query_stmt->rowCount()) :
return $query_stmt->fetch(PDO::FETCH_ASSOC);
else :
return false;
endif;
} catch (PDOException $e) {
return null;
}
}
}
Rest of the PHP files
register.php – For user registration.
login.php – For user login.
getUser.php – After login, this page is accessible with a valid token.
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: access");
header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
require __DIR__ . '/classes/Database.php';
$db_connection = new Database();
$conn = $db_connection->dbConnection();
function msg($success, $status, $message, $extra = [])
{
return array_merge([
'success' => $success,
'status' => $status,
'message' => $message
], $extra);
}
// DATA FORM REQUEST
$data = json_decode(file_get_contents("php://input"));
$returnData = [];
if ($_SERVER["REQUEST_METHOD"] != "POST") :
$returnData = msg(0, 404, 'Page Not Found!');
elseif ( !isset($data->name)
|| !isset($data->email)
|| !isset($data->password)
|| empty(trim($data->name))
|| empty(trim($data->email))
|| empty(trim($data->password))
) :
$fields = ['fields' => ['name', 'email', 'password']];
$returnData = msg(0, 422, 'Please Fill in all Required Fields!', $fields);
// IF THERE ARE NO EMPTY FIELDS THEN-
else :
$name = trim($data->name);
$email = trim($data->email);
$password = trim($data->password);
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) :
$returnData = msg(0, 422, 'Invalid Email Address!');
elseif (strlen($password) < 8) :
$returnData = msg(0, 422, 'Your password must be at least 8 characters long!');
elseif (strlen($name) < 3) :
$returnData = msg(0, 422, 'Your name must be at least 3 characters long!');
else :
try {
$check_email = "SELECT `email` FROM `users` WHERE `email`=:email";
$check_email_stmt = $conn->prepare($check_email);
$check_email_stmt->bindValue(':email', $email, PDO::PARAM_STR);
$check_email_stmt->execute();
if ($check_email_stmt->rowCount()) :
$returnData = msg(0, 422, 'This E-mail already in use!');
else :
$insert_query = "INSERT INTO `users`(`name`,`email`,`password`) VALUES(:name,:email,:password)";
$insert_stmt = $conn->prepare($insert_query);
// DATA BINDING
$insert_stmt->bindValue(':name', htmlspecialchars(strip_tags($name)), PDO::PARAM_STR);
$insert_stmt->bindValue(':email', $email, PDO::PARAM_STR);
$insert_stmt->bindValue(':password', password_hash($password, PASSWORD_DEFAULT), PDO::PARAM_STR);
$insert_stmt->execute();
$returnData = msg(1, 201, 'You have successfully registered.');
endif;
} catch (PDOException $e) {
$returnData = msg(0, 500, $e->getMessage());
}
endif;
endif;
echo json_encode($returnData);
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: access");
header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
require __DIR__.'/classes/Database.php';
require __DIR__.'/classes/JwtHandler.php';
function msg($success,$status,$message,$extra = []){
return array_merge([
'success' => $success,
'status' => $status,
'message' => $message
],$extra);
}
$db_connection = new Database();
$conn = $db_connection->dbConnection();
$data = json_decode(file_get_contents("php://input"));
$returnData = [];
// IF REQUEST METHOD IS NOT EQUAL TO POST
if($_SERVER["REQUEST_METHOD"] != "POST"):
$returnData = msg(0,404,'Page Not Found!');
// CHECKING EMPTY FIELDS
elseif(!isset($data->email)
|| !isset($data->password)
|| empty(trim($data->email))
|| empty(trim($data->password))
):
$fields = ['fields' => ['email','password']];
$returnData = msg(0,422,'Please Fill in all Required Fields!',$fields);
// IF THERE ARE NO EMPTY FIELDS THEN-
else:
$email = trim($data->email);
$password = trim($data->password);
// CHECKING THE EMAIL FORMAT (IF INVALID FORMAT)
if(!filter_var($email, FILTER_VALIDATE_EMAIL)):
$returnData = msg(0,422,'Invalid Email Address!');
// IF PASSWORD IS LESS THAN 8 THE SHOW THE ERROR
elseif(strlen($password) < 8):
$returnData = msg(0,422,'Your password must be at least 8 characters long!');
// THE USER IS ABLE TO PERFORM THE LOGIN ACTION
else:
try{
$fetch_user_by_email = "SELECT * FROM `users` WHERE `email`=:email";
$query_stmt = $conn->prepare($fetch_user_by_email);
$query_stmt->bindValue(':email', $email,PDO::PARAM_STR);
$query_stmt->execute();
// IF THE USER IS FOUNDED BY EMAIL
if($query_stmt->rowCount()):
$row = $query_stmt->fetch(PDO::FETCH_ASSOC);
$check_password = password_verify($password, $row['password']);
// VERIFYING THE PASSWORD (IS CORRECT OR NOT?)
// IF PASSWORD IS CORRECT THEN SEND THE LOGIN TOKEN
if($check_password):
$jwt = new JwtHandler();
$token = $jwt->jwtEncodeData(
'http://localhost/php_auth_api/',
array("user_id"=> $row['id'])
);
$returnData = [
'success' => 1,
'message' => 'You have successfully logged in.',
'token' => $token
];
// IF INVALID PASSWORD
else:
$returnData = msg(0,422,'Invalid Password!');
endif;
// IF THE USER IS NOT FOUNDED BY EMAIL THEN SHOW THE FOLLOWING ERROR
else:
$returnData = msg(0,422,'Invalid Email Address!');
endif;
}
catch(PDOException $e){
$returnData = msg(0,500,$e->getMessage());
}
endif;
endif;
echo json_encode($returnData);
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: access");
header("Access-Control-Allow-Methods: GET");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
require __DIR__.'/classes/Database.php';
require __DIR__.'/AuthMiddleware.php';
$allHeaders = getallheaders();
$db_connection = new Database();
$conn = $db_connection->dbConnection();
$auth = new Auth($conn, $allHeaders);
echo json_encode($auth->isValid());
Step 3 : Testing of the PHP login and registration API
POST - http://localhost/php-auth-api/register.php
Payload (JSON)
{
"name":"username",
"email":"useremail@mail.com",
"password":"user password" }
POST - http://localhost/php-auth-api/login.php
Payload (JSON)
{
"email":"useremail@mail.com",
"password":"user password"
}
GET - http://localhost/php-auth-api/getUser.php
Payload (Header)
Authorization - Bearer Token
Congratulations
Aww yeah, you successfully completed reading this tutorial and I hope you have not missed out any step.
People who read this also read
