Tuesday 20 February 2024

Converting Dynamic HTML to PDF in Node.js with Puppeteer


In this tutorial, we'll learn how to convert HTML content to a PDF file using Puppeteer in a Node.js environment. Puppeteer is a Node library that provides a high-level API to control headless Chrome or Chromium over the DevTools Protocol, making it a powerful tool for automating web tasks, including generating PDF files from HTML content.


Converting Dynamic HTML to PDF in Node.js with Puppeteer


Prerequisites


Before we begin, ensure you have the following installed:

  • Node.js (with npm)
  • MySQL (for the database setup, optional for this tutorial)
  • Basic understanding of Node.js and JavaScript

Setting up the Project


First, let's set up a Node.js project and install the necessary dependencies.

Create a new directory for your project and navigate into it:

	
		mkdir html-to-pdf-nodejs
		cd html-to-pdf-nodejs
	

Initialize a new Node.js project:

	
		npm init -y
	

Install the required dependencies (Express, MySQL, Puppeteer, Open):

	
		npm install express mysql2 puppeteer open
	

Database Structure


For convert dynamic HTML to PDF we need to fetch data from MySQL table. So run below sql script which will create sampledata table in your database.

	
		CREATE TABLE `sampledata` (
		  `id` mediumint unsigned NOT NULL AUTO_INCREMENT,
		  `name` varchar(255) DEFAULT NULL,
		  `phone` varchar(100) DEFAULT NULL,
		  `email` varchar(255) DEFAULT NULL,
		  `address` varchar(255) DEFAULT NULL,
		  `postalZip` varchar(10) DEFAULT NULL,
		  `region` varchar(50) DEFAULT NULL,
		  `country` varchar(100) DEFAULT NULL,
		  PRIMARY KEY (`id`)
		) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
		
		INSERT INTO `sampledata` VALUES (1,'Stephen Taylor','1-802-830-1866','auctor.nunc@hotmail.com','5659 Luctus Rd.','21408','Dadra and Nagar Haveli','Poland'),(2,'Mason George','1-343-545-7768','mauris@aol.edu','Ap #221-6699 Lacus. St.','921307','FATA','Costa Rica'),(3,'Hasad Donaldson','1-666-557-3187','et.euismod@google.edu','Ap #383-4682 Ornare Av.','818143','Kinross-shire','United Kingdom'),(4,'Hall Holland','(805) 418-1538','tempor.est@icloud.com','P.O. Box 358, 7624 Tincidunt Avenue','486262','Madrid','Indonesia'),(5,'Adam Hampton','1-421-241-5178','cubilia.curae@google.ca','P.O. Box 161, 1859 Iaculis Av.','44837','Brussels Hoofdstedelijk Gewest','South Korea'),(6,'Elizabeth Allison','(538) 834-6212','elit.dictum@hotmail.edu','867-6580 At St.','33668','Jeju','Pakistan'),(7,'Neve Barber','1-552-311-0208','vestibulum.nec.euismod@google.com','224-8122 Donec Road','51174','Santa Catarina','Netherlands'),(8,'Fatima Pope','(619) 278-1176','nulla.integer@hotmail.couk','649-1054 Ipsum Rd.','748321','Bahia','Austria'),(9,'Shad Cobb','1-778-327-3349','dignissim.maecenas.ornare@outlook.edu','6983 Magna. Rd.','2163','Xīběi','Philippines'),(10,'Zephr Ruiz','1-544-316-1144','luctus.ipsum@google.ca','634-2043 Cras Avenue','3845','Mecklenburg-Vorpommern','Sweden'),(11,'Juliet Lynn','(375) 573-6793','proin.dolor.nulla@yahoo.net','Ap #179-6441 Cum Rd.','71829','Calabria','Turkey'),(12,'Candice Medina','1-441-292-1278','integer.vulputate@icloud.org','953-188 Et Rd.','440326','Vorarlberg','Australia'),(13,'Rhea Roach','(635) 768-6867','vitae.velit@icloud.edu','543-5616 Sem Av.','869566','Burgenland','Canada'),(14,'Dean Hendrix','(362) 760-8321','nunc.pulvinar@protonmail.ca','Ap #905-5267 Arcu Street','6755-4242','National Capital Region','Indonesia'),(15,'Malachi Mitchell','1-586-881-4174','eget.lacus.mauris@icloud.ca','P.O. Box 183, 1479 Massa. St.','367458','Västra Götalands län','Indonesia'),(21,'Gabriel Acevedo','1-215-463-4511','dictum.cursus@outlook.com','5681 Sit Rd.','28846','Lombardia','Italy'),(22,'Beau Norris','1-563-287-4004','eros@google.edu','Ap #533-2583 Duis Rd.','R8T 1S4','Eastern Visayas','United States'),(23,'Kylan Mckinney','1-533-833-5567','eleifend.vitae@hotmail.net','333-2972 Nec, Road','72866','Leinster','Australia'),(24,'Stone Parsons','1-584-246-2228','aenean@outlook.com','923-5509 Etiam Street','Y1R 5X7','Zamboanga Peninsula','Nigeria'),(25,'Neve Sweet','(764) 167-2572','tellus.aenean@aol.net','558-1070 Sed, St.','1023 PS','Vienna','United Kingdom');
	

Creating the Server and HTML Template


Now, let's create a basic Express server that serves an HTML page with sample data fetched from a MySQL database. We'll also include a button to trigger the conversion of the HTML to a PDF file.

Create a file named app.js with the following content:

app.js
	
		const express = require('express');
		const mysql = require('mysql2');
		//Add puppeteer library
		const puppeteer = require('puppeteer');
		const app = express();
		const port = 3000;
		app.use(express.json());
		//Serve static files (including index.html) from the root directory
		app.use(express.static(__dirname));
		const database = mysql.createConnection({
			host : 'localhost',
			user : 'root',
			password : '123456789',
			database : 'testing'
		});

		database.connect((error)=> {
			if(error){
				console.error('Error connecting to MySQL : ', error);
			} else{
				console.log('Connected to MySQL database');
			}
		});

		app.get('/data', (request, response) => {
			response.sendFile(__dirname + '/data.html');
		});

		app.post('/getData', (request, response) => {
			database.query('SELECT * FROM sampledata', async (error, results) => {
				response.status(200).json(results);
			});
		});

		app.listen(port, () => {
			console.log(`Server is running on http://localhost:${port}`);   
		});
	

Create a file named data.html with the following content:

	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>How to Convert HTML to PDF in Node.js using Puppeteer</title>
			</head>
			<body>
				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">How to Convert HTML to PDF in Node.js using Puppeteer</h1>
					<div class="card">
						<div class="card-header">
							<div class="row">
								<div class="col col-6">Sample Data</div>
								<div class="col col-6">
									<a href="/convertPDF" class="btn btn-primary btn-sm float-end">Download in PDF</a>
								</div>
							</div>
						</div>
						<div class="card-body">
							<div class="table-responsive">
								<table class="table table-bordered table-striped">
									<thead>
										<tr>
											<th>Name</th>
											<th>Phone</th>
											<th>Email</th>
											<th>Address</th>
											<th>Zip</th>
											<th>Region</th>
											<th>Country</th>
										</tr>
									</thead>
									<tbody id="dataArea"></tbody>
								</table>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>
			getData();
			function getData(){
				fetch('/getData', {
					method: 'POST'
				})
				.then(response => {
					return response.json();
				})
				.then(data => {
					if(data.length > 0){
						let html = '';
						for(let i = 0; i < data.length; i++){
							html += `
							<tr>
								<td>${data[i].name}</td>
								<td>${data[i].phone}</td>
								<td>${data[i].email}</td>
								<td>${data[i].address}</td>
								<td>${data[i].postalZip}</td>
								<td>${data[i].region}</td>
								<td>${data[i].country}</td>
							</tr>
							`;
						}
						document.getElementById('dataArea').innerHTML = html;
					}
				})
				.catch(error => {
					// Handle errors
					//console.error(error);
					alert(error);
				});
			}
		</script>
	

Save this code in the root directory of your project.

HTML to PDF Conversion


We'll define a function convertHTMLToPDF in app.js file that takes HTML content as input, converts it to a PDF file using Puppeteer, and opens the generated PDF file.

app.js
	
		async function convertHTMLToPDF(htmlContent, pdfFilePath, margins = {top: '10mm', right: '10mm', bottom: '10mm', left: '10mm'}){
			const browser = await puppeteer.launch();
			const page = await browser.newPage();
			// Set the page content
			await page.setContent(htmlContent);
			// Generate PDF
			await page.pdf({ path : pdfFilePath, format : 'A4', margin : margins });
			// Open the generated PDF file in the default PDF viewer
			const open = await import('open');
			await open.default(pdfFilePath);
			//close the browser
			await browser.close();
		}
	

Serving HTML and Triggering Conversion


Finally, we'll set up routes to fetch data from MySQL table and convert into HTML and serve the HTML data and trigger the conversion to PDF when the user clicks on Download in PDF button.

app.js
	
		app.get('/convertPDF', async (request, response)=>{
			database.query('SELECT * FROM sampledata', async (error, results) => {
				let html = '';
				if(results.length > 0){
					html += `
					<table width="100%" border="1" cellpadding="5" cellspacing="0">
						<tr>
							<th width="20%">Name</th>
							<th width="10%">Phone</th>
							<th width="20%">Email</th>
							<th width="20%">Address</th>
							<th width="10%">Zip</th>
							<th width="10%">Region</th>
							<th width="10%">Country</th>
						</tr>
					`;
					results.map((row)=>{
						html += `
						<tr>
							<th>${row.name}</th>
							<th>${row.phone}</th>
							<th>${row.email}</th>
							<th>${row.address}</th>
							<th>${row.postalZip}</th>
							<th>${row.region}</th>
							<th>${row.country}</th>
						</tr>
						`;
					});
					html += `
					</table>
					`;
				}
				await convertHTMLToPDF(html, 'data.pdf');
			});
		});
	

Running the Server


To run the server, execute the following command:

	
		node app.js
	

Visit http://localhost:3000/data in your web browser to see the sample data table. Click the "Download in PDF" button to convert the HTML table to a PDF file.

Conclusion


Congratulations! You've learned how to convert HTML content to a PDF file in Node.js using Puppeteer. This technique can be useful for generating PDF reports, invoices, or any other printable documents from dynamic HTML content.

Feel free to customize the code to suit your specific requirements and explore additional features offered by Puppeteer for web automation and PDF generation.

Complete Source Code


app.js
	
		const express = require('express');
		const mysql = require('mysql2');
		//Add puppeteer library
		const puppeteer = require('puppeteer');
		const app = express();
		const port = 3000;
		app.use(express.json());
		//Serve static files (including index.html) from the root directory
		app.use(express.static(__dirname));
		const database = mysql.createConnection({
			host : 'localhost',
			user : 'root',
			password : '123456789',
			database : 'testing'
		});

		database.connect((error)=> {
			if(error){
				console.error('Error connecting to MySQL : ', error);
			} else{
				console.log('Connected to MySQL database');
			}
		});

		app.get('/data', (request, response) => {
			response.sendFile(__dirname + '/data.html');
		});

		app.post('/getData', (request, response) => {
			database.query('SELECT * FROM sampledata', async (error, results) => {
				response.status(200).json(results);
			});
		});

		async function convertHTMLToPDF(htmlContent, pdfFilePath, margins = {top: '10mm', right: '10mm', bottom: '10mm', left: '10mm'}){
			const browser = await puppeteer.launch();
			const page = await browser.newPage();
			// Set the page content
			await page.setContent(htmlContent);
			// Generate PDF
			await page.pdf({ path : pdfFilePath, format : 'A4', margin : margins });
			// Open the generated PDF file in the default PDF viewer
			const open = await import('open');
			await open.default(pdfFilePath);
			//close the browser
			await browser.close();
		}

		app.get('/convertPDF', async (request, response)=>{
			database.query('SELECT * FROM sampledata', async (error, results) => {
				let html = '';
				if(results.length > 0){
					html += `
					<table width="100%" border="1" cellpadding="5" cellspacing="0">
						<tr>
							<th width="20%">Name</th>
							<th width="10%">Phone</th>
							<th width="20%">Email</th>
							<th width="20%">Address</th>
							<th width="10%">Zip</th>
							<th width="10%">Region</th>
							<th width="10%">Country</th>
						</tr>
					`;
					results.map((row)=>{
						html += `
						<tr>
							<th>${row.name}</th>
							<th>${row.phone}</th>
							<th>${row.email}</th>
							<th>${row.address}</th>
							<th>${row.postalZip}</th>
							<th>${row.region}</th>
							<th>${row.country}</th>
						</tr>
						`;
					});
					html += `
					</table>
					`;
				}
				await convertHTMLToPDF(html, 'data.pdf');
			});
		});


		app.listen(port, () => {
			console.log(`Server is running on http://localhost:${port}`);   
		});
	

data.html
	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>How to Convert HTML to PDF in Node.js using Puppeteer</title>
			</head>
			<body>
				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">How to Convert HTML to PDF in Node.js using Puppeteer</h1>
					<div class="card">
						<div class="card-header">
							<div class="row">
								<div class="col col-6">Sample Data</div>
								<div class="col col-6">
									<a href="/convertPDF" class="btn btn-primary btn-sm float-end">Download in PDF</a>
								</div>
							</div>
						</div>
						<div class="card-body">
							<div class="table-responsive">
								<table class="table table-bordered table-striped">
									<thead>
										<tr>
											<th>Name</th>
											<th>Phone</th>
											<th>Email</th>
											<th>Address</th>
											<th>Zip</th>
											<th>Region</th>
											<th>Country</th>
										</tr>
									</thead>
									<tbody id="dataArea"></tbody>
								</table>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>
			getData();
			function getData(){
				fetch('/getData', {
					method: 'POST'
				})
				.then(response => {
					return response.json();
				})
				.then(data => {
					if(data.length > 0){
						let html = '';
						for(let i = 0; i < data.length; i++){
							html += `
							<tr>
								<td>${data[i].name}</td>
								<td>${data[i].phone}</td>
								<td>${data[i].email}</td>
								<td>${data[i].address}</td>
								<td>${data[i].postalZip}</td>
								<td>${data[i].region}</td>
								<td>${data[i].country}</td>
							</tr>
							`;
						}
						document.getElementById('dataArea').innerHTML = html;
					}
				})
				.catch(error => {
					// Handle errors
					//console.error(error);
					alert(error);
				});
			}
		</script>
	


Tuesday 13 February 2024

Simplifying User Authentication with JWT Tokens in Node.js


In modern web development, user authentication is a fundamental aspect of building secure applications. Implementing a login and registration system using JSON Web Tokens (JWT) in Node.js offers a robust solution that enhances security and simplifies user management. In this article, we'll explore how to implement user authentication using JWT tokens in a Node.js application.


Simplifying User Authentication with JWT Tokens in Node.js

What are JWT Tokens?


JWT tokens are an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. These tokens can be signed using a secret or a public/private key pair, providing a means of verifying the integrity of the information contained within.

  1. Step 1: Setting Up Your Node.js Environment
  2. Step 2: Creating the Express Server
  3. Step 3: Database Connection
  4. Step 4: Setting Up Routes
  5. Step 5: Implementing User Registration
  6. Step 6: Implementing User Login
  7. Step 7: Protecting Routes
  8. Step 8: Run Application
  9. Step 9: Conclusion

Step 1: Setting Up Your Node.js Environment


Ensure you have Node.js installed on your machine. If not, download and install it from the official Node.js website. Once installed, open your terminal and create a new directory for your project.

	
		mkdir node-jwt-auth
		cd node-jwt-auth
	

Initialize a new Node.js project and install the necessary dependencies.

	
		npm install express jsonwebtoken bcrypt body-parser mongoose
	

Step 2: Creating the Express Server


Create a file named app.js and set up a basic Express server.

app.js
	
		const express = require('express');
		const mysql = require('mysql2');
		const bcrypt = require('bcrypt');
		const jwt = require('jsonwebtoken');
		const app = express();
		const port = 3000;
		app.use(express.json());
		//Serve static files (including index.html) from the root directory
		app.use(express.static(__dirname));
	

Step 3: Database Connection


Under this app.js file we have to make MySQL Database connection. So user registration data will be stored under MySQL database.

app.js
	
		const database = mysql.createConnection({
			host : 'localhost',
			user : 'root',
			password : '123456789',
			database : 'testing'
		});

		database.connect((error)=> {
			if(error){
				console.error('Error connecting to MySQL : ', error);
			} else{
				console.log('Connected to MySQL database');
			}
		});
	

It will make database connection and also check that there is any error has been occured during database connection.

Below you can find MySQL table structure for user table. So you have to copy this .sql code and run in local MySQL database. So it will create user under which registration data will be stored.

	
		CREATE TABLE `user` (
		  `user_id` int NOT NULL AUTO_INCREMENT,
		  `user_email` varchar(70) DEFAULT NULL,
		  `user_password` varchar(70) DEFAULT NULL,
		  `user_name` varchar(45) DEFAULT NULL,
		  `email_verification_status` enum('Not Verified','Verified') DEFAULT NULL,
		  PRIMARY KEY (`user_id`)
		) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
	

Step 4: Setting Up Routes


Create routes under app.js file for handling user authentication and registration.

app.js
	
		app.get('/', (request, response)=>{
		
		});
		
		app.post('/register', async (request, response)=>{
		
		});
	

Define routes for user registration, login, and protected resources in the respective files.

Step 5: Implementing User Registration


First we have goes into '/' get route, and under this we have to write following code which will load index.html file on browser.

app.js
	
		app.get('/', (request, response)=>{
			response.sendFile(__dirname + '/index.html');
		});
	

After this, we have goes to index.html file and under this we have to create register form and then after we have to write JavaScript code for submit register form data using JavaScript fetch API. And here we have also use try catch block of handle error at front end side.

index.html
	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>Node.js Login Register using JWT Token</title>
			</head>
			<body>				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">Node.js Login Register using JWT Token</h1>
					<div class="row">
						<div class="col col-4"> </div>
						<div class="col col-4">
							<span id="msgArea"></span>
							<div class="card">
								<div class="card-header">Register</div>
								<div class="card-body">
									<form id="registerForm">
										<div class="mb-3">
											<label><b>Name</b></label>
											<input type="text" name="name" id="name" class="form-control" />
										</div>
										<div class="mb-3">
											<label><b>eMail</b></label>
											<input type="text" name="email" id="email" class="form-control" />
										</div>
										<div class="mb-3">
											<label><b>Password</b></label>
											<input type="password" name="password" id="password" class="form-control" />
										</div>
										<input type="submit" class="btn btn-primary" value="Register" />
									</form>
								</div>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>

		document.getElementById("registerForm").addEventListener('submit', async function(event){
			event.preventDefault();
			const name = document.getElementById("name").value;
			const email = document.getElementById("email").value;
			const password = document.getElementById("password").value;
			let messageArea = document.getElementById("msgArea");
			try{
				const response = await fetch('/register', {
					method : 'POST',
					headers : {
						'Content-Type': 'application/json'
					},
					body : JSON.stringify({name, email, password})
				});
				if(response.ok){
					messageArea.innerHTML = '<div class="alert alert-success">User registered successfully!</div>';
				} else {
					const data = await response.json();
					messageArea.innerHTML = `<div class="alert alert-info">Error : ${data.error}</div>`;
				}

			} catch(error){
				messageArea.innerHTML = '<div class="alert alert-danger">Internal Server Error</div>';
			}
		});

		</script>
	

Now in app.js, implement the route for user registration. Hash the user's password using bcrypt before storing it in the database and here it has also check email is already exists or not also.

app.js
	
		app.post('/register', async (request, response)=>{
			try{
				const {name, email, password} = request.body;
				if(!name || !email || !password){
					return response.status(400).json({error : 'Please provide all required fields'});
				}
				// Check if the email already exists in the database
				database.query('SELECT * FROM user WHERE user_email = ?', [email], async (error, results) =>{
					if(error){
						return response.status(500).json({error : 'Internal Server Error'});
					}
					if(results.length > 0){
						return response.status(400).json({error : 'Email already exists'});
					}
					const hashedPassword = await bcrypt.hash(password, 10);
					//Insert registeration data
					database.query('INSERT INTO user (user_email, user_password, user_name) VALUES (?, ?, ?)', [email, hashedPassword, name], (error) => {
						if(error){
							console.log(error);
							return response.status(500).json({error : 'Internal Server Error'});
						}
						return response.status(201).json({message : 'User registered successfully'});
					});
				});
			} catch(error){
				response.status(500).json({error : 'Internal Server Error'});
			}
		});
		app.listen(port, () => {
			console.log(`Server is running on http://localhost:${port}`);   
		});
	

Step 6: Implementing User Login


Now for create Login in this Node JS Application, first in app.js file we have go create route for load login form in the browser.

app.js
	
		app.get('/login', (request, response) => {
			response.sendFile(__dirname + '/login.html');
		});
	

So it will send login.html file in browser and display login login form on web page.

Next we have to create login.html file and under this file, we will write HTML code for display Login form and JavaScript code for submit login form data to server.

login.html
	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>Node.js Login Register using JWT Token</title>
			</head>
			<body>
				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">Node.js Login Register using JWT Token</h1>
					<div class="row">
						<div class="col col-4"> </div>
						<div class="col col-4">
							<span id="msgArea"></span>
							<div class="card">
								<div class="card-header">Login</div>
								<div class="card-body">
									<form id="loginForm">
										<div class="mb-3">
											<label><b>eMail</b></label>
											<input type="text" name="email" id="email" class="form-control" />
										</div>
										<div class="mb-3">
											<label><b>Password</b></label>
											<input type="password" name="password" id="password" class="form-control" />
										</div>
										<input type="submit" class="btn btn-primary" value="Login" />
									</form>
								</div>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>

		document.getElementById('loginForm').addEventListener('submit', async function(event){
			event.preventDefault();
			const email = document.getElementById('email').value;
			const password = document.getElementById('password').value;
			try {
				const response = await fetch('/login', {
					method : 'POST',
					headers : {
						'Content-Type': 'application/json',
					},
					body : JSON.stringify({ email, password })
				});
				const data = await response.json();
				if(response.ok){
					localStorage.setItem('token', data.token);
					window.location.href = '/welcome';
				} else {
					document.getElementById('msgArea').innerHTML = `<div class="alert alert-info">Error : ${data.error}</div>`;
				}
			} catch(error){
				document.getElementById('msgArea').innerHTML = '<div class="alert alert-danger">Internal Server Error</div>';
			}
		});

		</script>
	

Once login form data has been submitted then it will send login data to /login route of app.js file. And under this file it will validate user login data and here it also also compare simple login form password with hashed formatted password which is stored in database by using bcrypt library.

app.js
	
		app.post('/login', async (request, response) => {
			try {
				const {email, password} = request.body;
				if(!email || !password){
					return response.status(400).json({ error : 'Please provide all required fields'});
				}
				database.query('SELECT * FROM user WHERE user_email = ?', [email], async (error, results) => {
					if(results.length > 0){
						const user = results[0];
						if(await bcrypt.compare(password, user.user_password)){
							const token = jwt.sign({ userId : user.user_id }, secretKey, { expiresIn : '1h' });
							response.status(200).json({ token });
						} else {
							response.status(401).json({ error : 'Wrong Password' });
						}
					} else {
						response.status(401).json({ error : 'Wrong Email' });
					}
				});
			} catch(error){
				response.status(500).json({ error : 'Internal Server Error' });
			}
		});
	

Step 7: Protecting Routes


Once we have make login page, when user has been login into system then user data has been stored in JWT token. Now we want to verify that user has been login into system or not. So for this we have to make one middleware to check user is login or not. In middleware it will decode JWT token data and then after it has authenticate that user is login or not.

So for this first we have to create one button, so when we have click on that button then it will send request to Node server route for fetch data from JWT token. So when we have send request to server, then in header it will send encoded JWT token data.

welcome.html
	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>Node.js Login Register using JWT Token</title>
			</head>
			<body>
				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">Node.js Login Register using JWT Token</h1>
					<div class="row">
						<div class="col col-4"> </div>
						<div class="col col-4">
							<span id="msgArea"></span>
							<div class="card">
								<div class="card-header">Welcome Page</div>
								<div class="card-body">
									<h1 class="text-center">Welcome User</h1>
									<p class="text-center">
										<button type="button" class="btn btn-warning" onclick="getJWTData()">Get User ID</button>
										<button type="button" onclick="logout()" class="btn btn-primary">Logout</button>
									</p>
								</div>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>

		const token = localStorage.getItem('token');
		if(!token){
			window.location.href = '/login';
		}

		function logout(){
			localStorage.removeItem('token');
			window.location.href = '/login';
		}

		function getJWTData(){
			fetch('/getJWTData', {
				headers : {
					'Authorization' : token
				}
			})
			.then(response => {
				return response.json();
			})
			.then(data => {
				alert(`Login User ID is - ${data.userId}`);
			})
			.catch(error => {
				alert(error);
			});
		}

		</script>
	

Now at Node backend side code, we have to create getJWTData route and under this route we have to add verifyToken middleware. So this middleware code will be first executed and it will first receive JWT token data from HTTP header. And then after by using JWT library it will again decode that data. If data has been successfully decoded that it will execute other part of code. But Suppose there JWT token not found in HTTP headers then it will directly send error to client without executing next code. But suppose data has been decoded from JWT token then it will send back that data to client which will be pop up on web page. So this way it will fetch data from JWT token under Node JS application.

app.js
	
		// Middleware to check JWT token
		function verifyToken(request, response, next){
			const token = request.headers.authorization;
			if(!token){
				return response.status(401).json({ error : 'Access denied. No token provided.'});
			}
			try {
				const decoded = jwt.verify(token, secretKey);
				request.user = decoded;
				next();
			} catch(error){
				response.status(401).json({ error : 'Invalid token' });
			}
		}

		app.get('/getJWTData', verifyToken, (request, response) => {
			response.status(200).json({ userId : request.user.userId });
		});
	

Step 8: Run Application


Once our code is ready, now for check output in browser, we have goes to terminal and run node app.js command which will start node server.

And in browser we can open this Node application by open http://localhost:3000 this url.

Step 9: Conclusion


You've successfully implemented a login and registration system using JWT tokens in your Node.js application. This provides a secure way to manage user sessions and protect sensitive resources. With the flexibility of Node.js and the simplicity of JWT tokens, you can now build robust authentication systems for your web applications.

Complete Source Code


app.js
	
		const express = require('express');
		const mysql = require('mysql2');
		const bcrypt = require('bcrypt');
		const jwt = require('jsonwebtoken');
		const app = express();
		const port = 3000;
		app.use(express.json());
		//Serve static files (including index.html) from the root directory
		app.use(express.static(__dirname));
		const database = mysql.createConnection({
			host : 'localhost',
			user : 'root',
			password : '123456789',
			database : 'testing'
		});

		database.connect((error)=> {
			if(error){
				console.error('Error connecting to MySQL : ', error);
			} else{
				console.log('Connected to MySQL database');
			}
		});

		const secretKey = 'eyJhbGciOiJIUzI1NiJ9.eyJSb2xlIjoiQWRtaW4iLCJJc3N1ZXIiOiJJc3N1ZXIiLCJVc2VybmFtZSI6IkphdmFJblVzZSIsImV4cCI6MTcwNjg3ODE1MywiaWF0IjoxNzA2ODc4MTUzfQ.i4j208HUwM7JjLJL98o9EkE68Ia87i694iq7r67zRHM';

		app.get('/', (request, response)=>{
			response.sendFile(__dirname + '/index.html');
		});

		app.post('/register', async (request, response)=>{
			try{
				const {name, email, password} = request.body;
				if(!name || !email || !password){
					return response.status(400).json({error : 'Please provide all required fields'});
				}
				// Check if the email already exists in the database
				database.query('SELECT * FROM user WHERE user_email = ?', [email], async (error, results) =>{
					if(error){
						return response.status(500).json({error : 'Internal Server Error'});
					}
					if(results.length > 0){
						return response.status(400).json({error : 'Email already exists'});
					}
					const hashedPassword = await bcrypt.hash(password, 10);
					//Insert registeration data
					database.query('INSERT INTO user (user_email, user_password, user_name) VALUES (?, ?, ?)', [email, hashedPassword, name], (error) => {
						if(error){
							console.log(error);
							return response.status(500).json({error : 'Internal Server Error'});
						}
						return response.status(201).json({message : 'User registered successfully'});
					});
				});
			} catch(error){
				response.status(500).json({error : 'Internal Server Error'});
			}
		});

		app.get('/login', (request, response) => {
			response.sendFile(__dirname + '/login.html');
		});

		app.post('/login', async (request, response) => {
			try {
				const {email, password} = request.body;
				if(!email || !password){
					return response.status(400).json({ error : 'Please provide all required fields'});
				}
				database.query('SELECT * FROM user WHERE user_email = ?', [email], async (error, results) => {
					if(results.length > 0){
						const user = results[0];
						if(await bcrypt.compare(password, user.user_password)){
							const token = jwt.sign({ userId : user.user_id }, secretKey, { expiresIn : '1h' });
							response.status(200).json({ token });
						} else {
							response.status(401).json({ error : 'Wrong Password' });
						}
					} else {
						response.status(401).json({ error : 'Wrong Email' });
					}
				});
			} catch(error){
				response.status(500).json({ error : 'Internal Server Error' });
			}
		});

		app.get('/welcome', (request, response) => {
			response.sendFile(__dirname + '/welcome.html');
		});

		// Middleware to check JWT token
		function verifyToken(request, response, next){
			const token = request.headers.authorization;
			if(!token){
				return response.status(401).json({ error : 'Access denied. No token provided.'});
			}
			try {
				const decoded = jwt.verify(token, secretKey);
				request.user = decoded;
				next();
			} catch(error){
				response.status(401).json({ error : 'Invalid token' });
			}
		}

		app.get('/getJWTData', verifyToken, (request, response) => {
			response.status(200).json({ userId : request.user.userId });
		});


		app.listen(port, () => {
			console.log(`Server is running on http://localhost:${port}`);   
		});
	

index.html
	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>Node.js Login Register using JWT Token</title>
			</head>
			<body>
				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">Node.js Login Register using JWT Token</h1>
					<div class="row">
						<div class="col col-4"> </div>
						<div class="col col-4">
							<span id="msgArea"></span>
							<div class="card">
								<div class="card-header">Register</div>
								<div class="card-body">
									<form id="registerForm">
										<div class="mb-3">
											<label><b>Name</b></label>
											<input type="text" name="name" id="name" class="form-control" />
										</div>
										<div class="mb-3">
											<label><b>eMail</b></label>
											<input type="text" name="email" id="email" class="form-control" />
										</div>
										<div class="mb-3">
											<label><b>Password</b></label>
											<input type="password" name="password" id="password" class="form-control" />
										</div>
										<input type="submit" class="btn btn-primary" value="Register" />
									</form>
								</div>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>

		document.getElementById("registerForm").addEventListener('submit', async function(event){
			event.preventDefault();
			const name = document.getElementById("name").value;
			const email = document.getElementById("email").value;
			const password = document.getElementById("password").value;
			let messageArea = document.getElementById("msgArea");
			try{
				const response = await fetch('/register', {
					method : 'POST',
					headers : {
						'Content-Type': 'application/json'
					},
					body : JSON.stringify({name, email, password})
				});
				if(response.ok){
					messageArea.innerHTML = '<div class="alert alert-success">User registered successfully!</div>';
				} else {
					const data = await response.json();
					messageArea.innerHTML = `<div class="alert alert-info">Error : ${data.error}</div>`;
				}

			} catch(error){
				messageArea.innerHTML = '<div class="alert alert-danger">Internal Server Error</div>';
			}
		});

		</script>
	

login.html
	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>Node.js Login Register using JWT Token</title>
			</head>
			<body>
				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">Node.js Login Register using JWT Token</h1>
					<div class="row">
						<div class="col col-4"> </div>
						<div class="col col-4">
							<span id="msgArea"></span>
							<div class="card">
								<div class="card-header">Login</div>
								<div class="card-body">
									<form id="loginForm">
										<div class="mb-3">
											<label><b>eMail</b></label>
											<input type="text" name="email" id="email" class="form-control" />
										</div>
										<div class="mb-3">
											<label><b>Password</b></label>
											<input type="password" name="password" id="password" class="form-control" />
										</div>
										<input type="submit" class="btn btn-primary" value="Login" />
									</form>
								</div>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>

		document.getElementById('loginForm').addEventListener('submit', async function(event){
			event.preventDefault();
			const email = document.getElementById('email').value;
			const password = document.getElementById('password').value;
			try {
				const response = await fetch('/login', {
					method : 'POST',
					headers : {
						'Content-Type': 'application/json',
					},
					body : JSON.stringify({ email, password })
				});
				const data = await response.json();
				if(response.ok){
					localStorage.setItem('token', data.token);
					window.location.href = '/welcome';
				} else {
					document.getElementById('msgArea').innerHTML = `<div class="alert alert-info">Error : ${data.error}</div>`;
				}
			} catch(error){
				document.getElementById('msgArea').innerHTML = '<div class="alert alert-danger">Internal Server Error</div>';
			}
		});

		</script>
	

welcome.html
	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>Node.js Login Register using JWT Token</title>
			</head>
			<body>
				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">Node.js Login Register using JWT Token</h1>
					<div class="row">
						<div class="col col-4"> </div>
						<div class="col col-4">
							<span id="msgArea"></span>
							<div class="card">
								<div class="card-header">Welcome Page</div>
								<div class="card-body">
									<h1 class="text-center">Welcome User</h1>
									<p class="text-center">
										<button type="button" class="btn btn-warning" onclick="getJWTData()">Get User ID</button>
										<button type="button" onclick="logout()" class="btn btn-primary">Logout</button>
									</p>
								</div>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>

		const token = localStorage.getItem('token');
		if(!token){
			window.location.href = '/login';
		}

		function logout(){
			localStorage.removeItem('token');
			window.location.href = '/login';
		}

		function getJWTData(){
			fetch('/getJWTData', {
				headers : {
					'Authorization' : token
				}
			})
			.then(response => {
				return response.json();
			})
			.then(data => {
				alert(`Login User ID is - ${data.userId}`);
			})
			.catch(error => {
				alert(error);
			});
		}

		</script>
	



Friday 19 January 2024

How to Use jQuery Datatables in React.js using PHP with Server-side Processing


Introduction:


In the dynamic landscape of web development, harnessing the power of React.js along with jQuery DataTables can elevate your project's user interface and functionality. This tutorial will walk you through the seamless integration of jQuery DataTables in React.js, using PHP for efficient server-side processing. Follow these steps to enhance your web application's performance and deliver a smoother user experience.


How to Use jQuery Datatables in React.js using PHP with Server-side Processing




Step 1: Setting up Your React.js Project


Start by creating a new React application, so here in this tutorial, we have already describe step by step to install React JS Application under this React JS CRUD Application tutorial.

Step 2: Installing jQuery DataTables


Once we have set up React JS application in our computer, so next we have to download and install necessary dependencies in our React.js Application. So here we have to install jQuery, jQuery DataTables, Bootstrap 5 and Bootstrap 5 theme for DataTables. So for download and install this dependencies, we have goes to terminal and then after goes into our directory and run this NPM command.






npm install jquery
npm install bootstrap
npm install datatables.net
npm install datatables.net-bs5


Step 3: Creating a React Component for DataTables


Create a new component for DataTables integration. This component will serve as the foundation for displaying and managing your data:

src/Component/Datatables.jsx

import React, { useEffect } from 'react';

import $ from 'jquery';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'datatables.net-bs5/css/dataTables.bootstrap5.min.css';
import 'datatables.net-bs5';

const Datatables = () => {

	useEffect(() => {

		const dataTable = $('#datatable').DataTable({
			serverSide : true,
			processing : true,
			ajax : {
				url : 'http://localhost/tutorial/php-react-js-datatables/api/get.php',
				type : 'POST'
			},
			columns : [
				{ title : 'ID', data : 'user_id' },
				{ title : 'Name', data : 'user_name'},
				{ title : 'Email', data : 'user_email' }
			]
		});

		return () => {
			dataTable.destroy();
		};

	}, []);

	return (
		<div className="container">
			<h1 className="mt-5 mb-5 text-center"><b>DataTables in React JS with PHP MySQL Server-Side Processing</b></h1>
			<div className="card">
				<div className="card-header">DataTables in React JS with PHP MySQL Server-Side Processing</div>
				<div className="card-body">
					<table className="table table-bordered" id="datatable">
						<thead>
							<tr>
								<th>ID</th>
          						<th>Name</th>
          						<th>Email</th>
							</tr>
						</thead>
						<tbody></tbody>
					</table>
				</div>
			</div>
		</div>
	);

};

export default Datatables;


Step 4: Import DataTables Component


Let's add the DataTables component to the App.jsx file in your React.js project.

src/App.jsx

import { useState } from 'react'
/*import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'*/
import Datatables from './Component/Datatables';

function App() {
  

  return (
    <div>
        <Datatables />
    </div>
  )
}

export default App



In this tutorial, we import the DataTables and use it within the App component. This way, your DataTables component will be rendered when you run your React application.

Remember to adjust the import path if your DataTables.jsx is in a different directory. After making these changes, your React app should now successfully display the DataTable component.

Step 5: Implementing PHP Server-side Processing


For optimal handling of extensive datasets, implement server-side processing using PHP. Create a dedicated PHP script at api/get.php to fetch and process your data efficiently:

api/get.php

<?php

//get.php

header("Access-Control-Allow-Origin:* ");
header("Access-Control-Allow-Headers: *");
header("Access-Control-Allow-Methods: *");

$connect = new PDO("mysql:host=127.0.0.1;dbname=testing", "root", "password");

$columns = array(
	'user_id',
    'user_name',
    'user_email'
);

$query = "SELECT user_id, user_name, user_email FROM users";

$totalRecordStatement = $connect->prepare($query);
$totalRecordStatement->execute();
$totalRecord = $totalRecordStatement->rowCount();

if(isset($_POST['search']['value']))
{
	$query .= ' WHERE user_id LIKE "%'.$_POST["search"]["value"].'%" ';
	$query .= 'OR user_name LIKE "%'.$_POST["search"]["value"].'%" ';
	$query .= 'OR user_email LIKE "%'.$_POST["search"]["value"].'%" ';
}

if(isset($_POST['order']))
{
	$query .= 'ORDER BY ' . $columns[$_POST['order']['0']['column']] . ' ' . $_POST['order']['0']['dir'] . ' ';
}
else
{
	$query .= 'ORDER BY user_id DESC ';
}

$filteredRecordStatement = $connect->prepare($query);
$filteredRecordStatement->execute();
$filteredRecord = $filteredRecordStatement->rowCount();

if($_POST['length'] != -1)
{
	$query .= 'LIMIT ' .  $_POST['start'] . ', ' . $_POST['length'];
}

$statement = $connect->prepare($query);
$statement->execute();
$data = $statement->fetchAll(PDO::FETCH_ASSOC);

$response = array(
	'draw'				=>	intval($_POST['draw']),
	'recordsTotal'		=>	$totalRecord,
	'recordsFiltered'	=>	$filteredRecord,
	'data'				=>	$data
);

echo json_encode($response);

?>


Conclusion:


You've successfully integrated jQuery DataTables with React.js using PHP for server-side processing. This comprehensive guide empowers you to create data-driven web applications with enhanced user interfaces and optimized performance. Experiment with DataTables options and React.js features to elevate your development projects.







Tuesday 9 January 2024

Mastering User Registration and Email Verification in PHP with JWT Tokens: A Comprehensive Guide


In the ever-evolving landscape of web development, ensuring a secure and streamlined user registration process is paramount. One powerful way to enhance the security of your PHP-based applications is by implementing user registration and email verification using JSON Web Tokens (JWT). In this guide, we'll walk you through the process step by step, empowering you to bolster the authentication mechanisms of your PHP projects.


Mastering User Registration and Email Verification in PHP with JWT Tokens: A Comprehensive Guide


Understanding the Basics


What is JWT?


JSON Web Tokens (JWT) provide a secure and compact way to transmit information between parties. In the context of user authentication, JWTs can be used to securely store user data and ensure that information is not tampered with during transmission.

Why PHP?


PHP remains a popular server-side scripting language, particularly for web development. Its versatility, ease of use, and extensive community support make it an excellent choice for implementing robust authentication systems.

Step-by-Step Guide


1. Setting Up Your PHP Environment


Ensure that your PHP environment is configured correctly. This includes setting up a database to store user information securely.


CREATE TABLE `user` (
  `user_id` int NOT NULL AUTO_INCREMENT,
  `user_email` varchar(70) DEFAULT NULL,
  `user_password` varchar(45) DEFAULT NULL,
  `user_name` varchar(45) DEFAULT NULL,
  `email_verification_status` enum('Not Verified','Verified') DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `user` VALUES (1,'johnsmith@gmail.com','password','John Smith','Verified'),(16,'peterparker@mailinator.com','password','Peter Parker','Verified'),(17,'donna@mailinator.com','password','Donna Hubber','Verified'),(18,'mike@mailinator.com','password','Mike','Verified');


2. Integrating JWT Library


Choose a reliable JWT library for PHP, such as Firebase JWT. Integrate it into your project to start creating and validating JWTs.


composer require firebase/php-jwt


3. User Registration


Implement a user registration system that securely stores user data in your database. Hash passwords using strong encryption algorithms to enhance security.

4. Generating JWTs


Upon successful registration, generate a JWT containing relevant user information. This token will serve as a secure means of verifying the user's identity in subsequent requests.

5. Email Verification


Send a verification email containing a link with a JWT to the user's registered email address. This link will confirm the user's identity and activate their account.

6. Token Validation


Implement a mechanism to validate JWTs in subsequent user requests. This ensures that only authenticated users can access protected resources.

Best Practices and Security Measures


1. Use HTTPS


Ensure your application is served over HTTPS to encrypt data transmitted between the user and the server, preventing man-in-the-middle attacks.

2. Token Expiry


Set a reasonable expiration time for your JWTs to mitigate the risk of unauthorized access.

3. Secure Database Storage


Employ secure practices for storing user data in the database, such as hashing and salting passwords.

4. Rate Limiting


Implement rate limiting to prevent brute-force attacks on the authentication system.

Conclusion


By following this comprehensive guide, you'll be well-equipped to implement a robust user registration and email verification system using PHP and JWT. Enhance the security of your applications, protect user data, and provide a seamless experience for your users. Stay ahead in the world of web development by mastering the art of authentication with PHP and JWT tokens.





Source Code


register.php

<?php 

//register.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$error = '';

$message = '';

if(isset($_POST['register']))
{
	$connect = new PDO("mysql:host=localhost; dbname=testing", "root", "password");

	if(empty($_POST['name']))
	{
		$error = 'Please Enter Name Details';
	}
	else if(empty($_POST['email']))
	{
		$error = 'Please Enter Email Details';
	}
	else if(empty($_POST['password']))
	{
		$error = 'Please Enter Password Details';
	}
	else
	{
		$query = "SELECT user_id FROM user WHERE user_email = ?";
		$statement = $connect->prepare($query);
		$statement->execute([$_POST["email"]]);
		if($statement->rowCount() > 0)
		{
			$error = 'Email Alaready Exists';
		}
		else
		{
			$data = array(
				':user_email'		=>	trim($_POST['email']),
				':user_password'	=>	trim($_POST['password']),
				':user_name'		=>	trim($_POST['name']),
				':email_verification_status'	=>	'Not Verified'
			);

			$insertQuery = "INSERT INTO user (user_email, user_password, user_name, email_verification_status) VALUES (:user_email, :user_password, :user_name, :email_verification_status)";
			$statement = $connect->prepare($insertQuery);
			if($statement->execute($data))
			{
				$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';

				$payload = array(
					'email'		=>	trim($_POST['email'])
				);

				$token = JWT::encode($payload, $key, 'HS256');

				$verificationLink = 'http://localhost/tutorial/php-jwt-login/verify.php?token='.$token;

				$mail = new PHPMailer(true);
				$mail->isSMTP();
				$mail->Host = 'smtp.gmail.com';
				$mail->SMTPAuth = true;
				$mail->Username = 'your gmail address';
				$mail->Password = 'xxx'; //Here you have to define your gmail password
				$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
				$mail->Port = 587;
				$mail->setFrom('sender@email.com', 'sender@email.com');
				$mail->addAddress(trim($_POST['email']), trim($_POST['name']));
				$mail->isHTML(true);
				$mail->Subject = 'Verify Your Email Address';
				$mail->Body = '
				<p>Hi,</p>
			    <p>Thank you for registering with us! To complete your registration and activate your account, please click on the following link:</p>
			    <p><a href="'.$verificationLink.'">'.$verificationLink.'</a></p>
			    <p>Thank you,<br />Webslesson.info</p>
				';
				$mail->send();
				$message = 'Verification eMail has been send! Registration Complete!';
			}
		}
	}
}

?>

<!doctype html>
<html lang="en">
  	<head>
    	<!-- Required meta tags -->
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">

    	<!-- Bootstrap CSS -->
    	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    	<title>PHP Registration & Email Validation using JWT Token</title>
  	</head>
  	<body>
    	<div class="container">
    		<h1 class="text-center mt-5 mb-5">PHP Registration & Email Validation using JWT Token</h1>
    		<div class="row">
    			<div class="col-md-4">&nbsp;</div>
    			<div class="col-md-4">
    				<?php

    				if($error !== '')
    				{
    					echo '<div class="alert alert-danger">'.$error.'</div>';
    				}

    				if($message !== '')
    				{
    					echo '<div class="alert alert-success">'.$message.'</div>';
    				}

    				?>
		    		<div class="card">
		    			<div class="card-header">Register</div>
		    			<div class="card-body">
		    				<form method="post">
		    					<div class="mb-3">
			    					<label>Name</label>
			    					<input type="text" name="name" class="form-control" />
			    				</div>
			    				<div class="mb-3">
			    					<label>Email</label>
			    					<input type="email" name="email" class="form-control" />
			    				</div>
			    				<div class="mb-3">
			    					<label>Password</label>
			    					<input type="password" name="password" class="form-control" />
			    				</div>
			    				<div class="text-center">
			    					<input type="submit" name="register" value="Register" class="btn btn-primary" />
			    				</div>
		    				</form>
		    			</div>
		    		</div>
		    	</div>
	    	</div>
    	</div>
  	</body>
</html>


verify.php

<?php

//verify.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';

$token = '';
$payload = array();

if(isset($_GET['token']))
{
	$connect = new PDO("mysql:host=localhost; dbname=testing", "root", "password");
	$decoded = JWT::decode($_GET['token'], new Key($key, 'HS256'));
	$checkQuery = 'SELECT email_verification_status FROM user WHERE user_email = "'.$decoded->email.'"';
	$result = $connect->query($checkQuery);
	foreach($result as $row)
	{
		if($row['email_verification_status'] === 'Verified')
		{
			$payload = array(
				'msg'	=>	'Your Email Already Verified, You can login'
			);
		}
		else
		{
			$query = 'UPDATE user SET email_verification_status = "Verified" WHERE user_email = "'.$decoded->email.'"';
			$statement = $connect->prepare($query);
			$statement->execute();
			$payload = array(
				'msg'	=>	'Email Successfully verify, now you can login'
			);
		}
		$token = JWT::encode($payload, $key, 'HS256');
		header('location:index.php?token='.$token);
	}
}

?>


index.php

<?php

//index.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';

$message = '';
$error = '';

if(isset($_GET['token']))
{
	$decoded = JWT::decode($_GET['token'], new Key($key, 'HS256'));
	$message = $decoded->msg;
}

if(isset($_POST["login"]))
{
	$connect = new PDO("mysql:host=localhost;dbname=testing", "root", "password");

	if(empty($_POST["email"])){
		$error = 'Please Enter Email Details';
	} else if(empty($_POST["password"])){
		$error = 'Please Enter Password Details';
	} else {
		$query = "SELECT * FROM user WHERE user_email = ?";
		$statement = $connect->prepare($query);
		$statement->execute([$_POST["email"]]);
		$data = $statement->fetch(PDO::FETCH_ASSOC);
		if($data){
			if($data['user_password'] ===  $_POST['password']){
				
				$token = JWT::encode(
					array(
						'iat'		=>	time(),
						'nbf'		=>	time(),
						'exp'		=>	time() + 3600,
						'data'	=> array(
							'user_id'	=>	$data['user_id'],
							'user_name'	=>	$data['user_name']
						)
					),
					$key,
					'HS256'
				);
				setcookie("token", $token, time() + 3600, "/", "", true, true);
				header('location:welcome.php');

			} else {
				$error = 'Wrong Password';
			}
		} else {
			$error = 'Wrong Email Address';
		}
	}
}

?>


<!doctype html>
<html lang="en">
  	<head>
    	<!-- Required meta tags -->
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">

    	<!-- Bootstrap CSS -->
    	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    	<title>How to Create Login using JWT Token in PHP</title>
  	</head>
  	<body>
    	<div class="container">
    		<h1 class="text-center mt-5 mb-5">How to Create Login using JWT Token in PHP</h1>
    		<div class="row">
    			<div class="col-md-4">&nbsp;</div>
    			<div class="col-md-4">
    				<?php

    				if($error !== '')
    				{
    					echo '<div class="alert alert-danger">'.$error.'</div>';
    				}

    				if($message !== '')
    				{
    					echo '<div class="alert alert-info">'.$message.'</div>';
    				}

    				?>
		    		<div class="card">
		    			<div class="card-header">Login</div>
		    			<div class="card-body">
		    				<form method="post">
		    					<div class="mb-3">
			    					<label>Email</label>
			    					<input type="email" name="email" class="form-control" />
			    				</div>
			    				<div class="mb-3">
			    					<label>Password</label>
			    					<input type="password" name="password" class="form-control" />
			    				</div>
			    				<div class="text-center">
			    					<input type="submit" name="login" class="btn btn-primary" value="Login" />
			    				</div>
		    				</form>
		    			</div>
		    		</div>
		    	</div>
	    	</div>
    	</div>
  	</body>
</html>


welcome.php

<?php

//welcome.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';

if(isset($_COOKIE['token'])){
	$decoded = JWT::decode($_COOKIE['token'], new Key($key, 'HS256'));
} else {
	header('location:index.php');
}

?>

<!doctype html>
<html lang="en">
  	<head>
    	<!-- Required meta tags -->
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">

    	<!-- Bootstrap CSS -->
    	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    	<title>How to Create Login in PHP using JWT Token</title>
  	</head>
  	<body>
    	<div class="container">
    		<h1 class="text-center mt-5 mb-5">How to Create Login in PHP using JWT Token</h1>
    		<div class="row">
    			<div class="col-md-4">&nbsp;</div>
    			<div class="col-md-4 text-center">
    				<h1>Welcome <b><?php echo $decoded->data->user_name; ?></b></h1>
    				<a href="logout.php">Logout</a>
    				
		    	</div>
	    	</div>
    	</div>
  	</body>
</html>


logout.php

<?php

//logout.php

setcookie("token", "", time() - 3600,  "/", "", true, true);

header('location:index.php');

?>


Tuesday 2 January 2024

Create a Secure Login with JWT Tokens in PHP: A Comprehensive Tutorial

In the world of web development, security is paramount, especially when it comes to user authentication. One effective way to enhance the security of your PHP applications is by implementing JWT (JSON Web Token) based login systems. In this comprehensive tutorial, we will guide you through the process of creating a secure login mechanism using JWT Tokens in PHP.

Create a Secure Login with JWT Tokens in PHP: A Comprehensive Tutorial

Why Choose JWT Tokens?


JWT Tokens offer a robust and efficient method for handling user authentication. They are compact, self-contained, and can be easily transmitted between parties. By leveraging JWT Tokens, you can ensure a secure and scalable login system for your PHP applications.

Prerequisites


Before we dive into the tutorial, make sure you have the following prerequisites in place:

  • Basic understanding of PHP programming.
  • A web server with PHP support.
  • A text editor for code editing.

Step 1: Setting Up Your PHP Environment


Begin by setting up your PHP environment. Ensure that you have PHP installed on your server, and create a new directory for your project. This will be the foundation for our secure login system.


// Sample PHP code for directory structure
/project-root
|-- index.php
|-- welcome.php
|-- logout.php
    |-- Before we dive into the tutorial, make sure you have the following prerequisites in place:





Step 2: Installing Dependencies


We will need a library to handle JWT operations. For this tutorial, we will use the popular `firebase/php-jwt` library. Install it using Composer:


composer require firebase/php-jwt


This library will simplify the creation, validation, and decoding of JWT Tokens in your PHP application.

Step 3: Creating the User Database


For our tutorial, let's assume you have a MySQL database named testing with a table named user. This table should contain fields like user_id, user_email, user_password, user_name and any other user-related information you need.


CREATE TABLE `user` (
  `user_id` int NOT NULL AUTO_INCREMENT,
  `user_email` varchar(70) DEFAULT NULL,
  `user_password` varchar(45) DEFAULT NULL,
  `user_name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `user` VALUES (1,'johnsmith@gmail.com','password','John Smith');


Step 4: Building the Login System


Now, let's create the login system (login.php) that verifies user credentials and generates a JWT Token upon successful authentication.

index.php

<?php

//index.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;

$error = '';

if(isset($_POST["login"]))
{
	$connect = new PDO("mysql:host=localhost;dbname=testing", "root", "password");

	if(empty($_POST["email"])){
		$error = 'Please Enter Email Details';
	} else if(empty($_POST["password"])){
		$error = 'Please Enter Password Details';
	} else {
		$query = "SELECT * FROM user WHERE user_email = ?";
		$statement = $connect->prepare($query);
		$statement->execute([$_POST["email"]]);
		$data = $statement->fetch(PDO::FETCH_ASSOC);
		if($data){
			if($data['user_password'] ===  $_POST['password']){
				$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';
				$token = JWT::encode(
					array(
						'iat'		=>	time(),
						'nbf'		=>	time(),
						'exp'		=>	time() + 3600,
						'data'	=> array(
							'user_id'	=>	$data['user_id'],
							'user_name'	=>	$data['user_name']
						)
					),
					$key,
					'HS256'
				);
				setcookie("token", $token, time() + 3600, "/", "", true, true);
				header('location:welcome.php');

			} else {
				$error = 'Wrong Password';
			}
		} else {
			$error = 'Wrong Email Address';
		}
	}
}

?>


<!doctype html>
<html lang="en">
  	<head>
    	<!-- Required meta tags -->
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">

    	<!-- Bootstrap CSS -->
    	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    	<title>How to Create Login using JWT Token in PHP</title>
  	</head>
  	<body>
    	<div class="container">
    		<h1 class="text-center mt-5 mb-5">How to Create Login using JWT Token in PHP</h1>
    		<div class="row">
    			<div class="col-md-4">&nbsp;</div>
    			<div class="col-md-4">
    				<?php

    				if($error !== '')
    				{
    					echo '<div class="alert alert-danger">'.$error.'</div>';
    				}

    				?>
		    		<div class="card">
		    			<div class="card-header">Login</div>
		    			<div class="card-body">
		    				<form method="post">
		    					<div class="mb-3">
			    					<label>Email</label>
			    					<input type="email" name="email" class="form-control" />
			    				</div>
			    				<div class="mb-3">
			    					<label>Password</label>
			    					<input type="password" name="password" class="form-control" />
			    				</div>
			    				<div class="text-center">
			    					<input type="submit" name="login" class="btn btn-primary" value="Login" />
			    				</div>
		    				</form>
		    			</div>
		    		</div>
		    	</div>
	    	</div>
    	</div>
  	</body>
</html>


The above code is a PHP script that handles user authentication using JWT (JSON Web Token) in a web application. This above code demonstrates a basic user authentication flow using JWT tokens in PHP, integrating database queries, JWT token generation, and error handling for a secure login system. Make sure to adapt and enhance it according to your specific project requirements and security considerations.

The HTML section contains a simple form for user login. It uses Bootstrap for styling.

welcome.php

<?php

//welcome.php

require 'vendor/autoload.php';

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$key = '1a3LM3W966D6QTJ5BJb9opunkUcw_d09NCOIJb9QZTsrneqOICoMoeYUDcd_NfaQyR787PAH98Vhue5g938jdkiyIZyJICytKlbjNBtebaHljIR6-zf3A2h3uy6pCtUFl1UhXWnV6madujY4_3SyUViRwBUOP-UudUL4wnJnKYUGDKsiZePPzBGrF4_gxJMRwF9lIWyUCHSh-PRGfvT7s1mu4-5ByYlFvGDQraP4ZiG5bC1TAKO_CnPyd1hrpdzBzNW4SfjqGKmz7IvLAHmRD-2AMQHpTU-hN2vwoA-iQxwQhfnqjM0nnwtZ0urE6HjKl6GWQW-KLnhtfw5n_84IRQ';

if(isset($_COOKIE['token'])){
	$decoded = JWT::decode($_COOKIE['token'], new Key($key, 'HS256'));
} else {
	header('location:index.php');
}

?>

<!doctype html>
<html lang="en">
  	<head>
    	<!-- Required meta tags -->
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width, initial-scale=1">

    	<!-- Bootstrap CSS -->
    	<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

    	<title>How to Create Login in PHP using JWT Token</title>
  	</head>
  	<body>
    	<div class="container">
    		<h1 class="text-center mt-5 mb-5">How to Create Login in PHP using JWT Token</h1>
    		<div class="row">
    			<div class="col-md-4">&nbsp;</div>
    			<div class="col-md-4 text-center">
    				<h1>Welcome <b><?php echo $decoded->data->user_name; ?></b></h1>
    				<a href="logout.php">Logout</a>
    				
		    	</div>
	    	</div>
    	</div>
  	</body>
</html>


This PHP script (welcome.php) is responsible for displaying a welcome page for authenticated users.

This script checks for a valid JWT token in the user's cookie. If a token is present, it decodes the token to retrieve user information and displays a welcome message. If no token is found, the user is redirected to the login page. The welcome page includes a logout link, which presumably leads to a logout script (logout.php).

logout.php

<?php

//logout.php

setcookie("token", "", time() - 3600,  "/", "", true, true);

header('location:index.php');

?>





The provided PHP script (logout.php) is responsible for logging out a user from the application.

This script is a simple logout mechanism for a web application. It clears the authentication token stored in the user's browser by deleting the corresponding cookie and then redirects the user to the login page to ensure a logged-out state. This is a common practice to terminate a user's session and enhance security.

Conclusion


Congratulations! You've successfully created a secure login system using JWT Tokens in PHP. This comprehensive tutorial covered setting up your PHP environment, installing dependencies, creating a user database, implementing user registration, building the login system, and securing your application.

By following these steps, you've enhanced the security of your PHP application, providing a robust authentication mechanism for your users. Implementing JWT-based login systems is a crucial step towards creating secure, scalable, and reliable web applications.

Feel free to adapt and expand upon this tutorial to meet the specific requirements of your project. Happy coding!

Remember to regularly update your dependencies, follow best practices, and stay informed about the latest security standards to ensure the ongoing security of your PHP applications.