Securing Your CodeIgniter REST API: Implementing JWT Token Authentication(Login) and Protected API Endpoints

Raguraj Sivanantham
5 min readNov 21, 2023

--

What is JWT Token?

JWT stands for “JSON Web Token,” and it is a compact and self-contained way to represent information between two parties. It is often used for securely transmitting information between a client (such as a web browser) and a server or between different parts of a web application.

JWTs are structured as JSON objects and consist of three parts:

JWT Token Structure

How JWT Token helps in REST API?

JWT tokens help REST APIs by providing a secure and stateless method for user authentication and authorization. Clients receive a token upon login, which they include in subsequent API requests. The server verifies the token’s authenticity and extracts user information for authentication and authorization, eliminating the need for server-side sessions and frequent database queries. This approach promotes scalability, simplifies architecture, and enables secure cross-origin requests in web applications, making REST APIs more efficient and suitable for modern app development.

How to Implement JWT Token in CodeIgniter 3?

Step 1: Basic Setup

1) Download CodeIgniter 3 from https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.1.13 extract and paste the file inside the www or htdocs folder and rename it as authentication.

2) Now we need to set the base URL. So, Goto config folder and open config.php and add value to $config[‘base_url’] like this;

$config[‘base_url’] = ‘http://localhost/authentication/';

3) Download following php-jwt.rar and extract the file. then add the folder inside the third_party folder (application → third_party) : download

4) Add Following Authorization_Token.php under libraries (application → libraries) folder: Download

5) Now we need to load the library. So, Goto config folder (application → config) and open autoload.php

6) In autoload.php add following values to $autoload[‘libraries’]

$autoload[‘libraries’] = array(“session”,”form_validation”,”email”,”Authorization_Token”);

7) Go to config folder and create file jwt.php and add this configuration

Now Basic Steps to implement JWT token is done. Now let’s create a controller and implement a login controller.

Step 2:

Create Auth.php under controllersfolder and add following code,

<?php
defined('BASEPATH') or exit('No direct script access allowed');

class Auth extends CI_Controller
{

public function __construct($config = "rest")
{
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Content-Length, Accept-Encoding,Authorization");
parent::__construct();
}

public function login()
{
if ($this->input->method() === 'post') {
$email = $this->input->post('email');
$password = $this->input->post('password');

if ($email == "test@mail.com" and $password == "test") {
$token_data['userEmail'] = $email;
$token_data['userRole'] = "Admin";
$tokenData = $this->authorization_token->generateToken($token_data);
return $this->sendJson(array("token" => $tokenData, "status" => true, "response" => "Login Success!"));
} else {
return $this->sendJson(array("token" => null, "status" => false, "response" => "Login Failed!"));
}
} else {
return $this->sendJson(array("message" => "POST Method", "status" => false));
}
}

private function sendJson($data)
{
$this->output->set_header('Content-Type: application/json; charset=utf-8')->set_output(json_encode($data));
}
}

Login Function: The login function is responsible for handling user login requests. It checks if the HTTP request method is POST, which is typically used for submitting login credentials.

Inside the login function:

  • It retrieves the email and password from the POST request data.
  • It checks if the provided email and password match a predefined set of credentials (in this case, "test@mail.com" and "test"). If they match, it proceeds to create a JWT token.
  • If the credentials match, it creates a token_data array containing the user’s email and role, and then generates a JWT token using the authorization_token->generateToken method.
  • If the credentials do not match, it returns a JSON response indicating login failure.

Open post man and send POST Request to check the response of this Login end point.

Now, Lets see How to create an Authorized API End point

  1. Go to Controller folder and create file Secured.php with following content
<?php
defined('BASEPATH') or exit('No direct script access allowed');

class Secured extends CI_Controller
{
public function __construct($config = "rest")
{
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Headers: Content-Type, Content-Length, Accept-Encoding,Authorization");
parent::__construct();
}

public function addProduct()
{
$headers = $this->input->request_headers();
if (isset($headers['Authorization'])) {
$decodedToken = $this->authorization_token->validateToken($headers['Authorization']);
if ($decodedToken['status']) {
if ($this->input->method() === 'post') {
// Business Logic of the endpoint here....
return $this->sendJson(array("response" => "API End point accessed successfuly !", "status" => false));
} else {
return $this->sendJson(array("response" => "POST Method", "status" => false));
}
} else {
return $this->sendJson(array("status" => false, "response" => "Invalid Token"));
}
} else {
return $this->sendJson(array("status" => true, "response" => "Token Required"));
}
}

private function sendJson($data)
{
$this->output->set_header('Content-Type: application/json; charset=utf-8')->set_output(json_encode($data));
}
}

Lets access the End Point and Check the results using postman !

Protected End Point With no Authorization Header
Protected End Point with Authorization header

If you want to add user roles protected API end points, You can simply send user role when user login to the system and send that Authorization token by header from frontend in each request to backend. In backend you can write logic to check whether requested user has access or not.

You can decode and check the encoded JWT token using jwt.io website. Just go to the website and paste the token

Then, How it is being still secure ?

Check this project on GitHub Repository : https://github.com/sragu2000/jwt_auth_codeigniter3

--

--

Raguraj Sivanantham

MERN Stack, Laravel, CodeIgniter | IT Enthusiast | Undergraduate at University of Moratuwa | B.Sc (Hons.) in Information Technology and Management