Using .env File in CodeIgniter 3

Learn how to use the .env file in CodeIgniter 3 to securely manage your environment variables and improve your application’s configuration structure.

Using environment variables via a .env file is a common best practice to keep sensitive configuration (like database credentials or any other secret or api keys) out of your codebase. .env file support is not provided in CodeIgniter 3 out of the box, but you can easily integrate it using the vlucas/phpdotenv library.

This guide will show you how to add .env file support in a CodeIgniter 3 application using the vlucas/phpdotenv library with Composer autoload enabled.

Prerequisites

Ensure your CodeIgniter project has Composer enabled by checking the following in application/config/config.php:

$config['composer_autoload'] = TRUE;

Step-by-Step Setup

The following are the steps to implement .env file support.

Step 1. Install vlucas/phpdotenv via Composer

In Codeigniter 3, composer.json is not available at the project root, but inside the application directory. So, to install any composer library, you have to first navigate to the application directory.

cd application/
composer require vlucas/phpdotenv

It will install the core files to add support for .env files.

Step 2. Create the .env File

At the root of your project (same level as index.php), create a file named .env with database configuration variables as a content:

DB_HOST=localhost
DB_USERNAME=root
DB_PASSWORD=secret
DB_NAME=my_database

3. Load the .env in index.php

Open your index.php file and add the following code before the line that bootstraps CodeIgniter:

require_once __DIR__ . '/vendor/autoload.php';

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

Add the above code in index.php file before the following line:

require_once BASEPATH.'core/CodeIgniter.php';

For older versions (PHP < 7.1 or Dotenv v2):

$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();

This will load the .env file variables using the phpdotenv library. Now, all the variables used in .env file can be used in any code of the project.

4. Use Environment Variables in database.php

We defined the database configuration variables inside the .env file. To use these variables, open application/config/database.php and update the code as follows:

$db['default'] = array(
    'hostname' => getenv('DB_HOST'),
    'username' => getenv('DB_USERNAME'),
    'password' => getenv('DB_PASSWORD'),
    'database' => getenv('DB_NAME'),
    'dbdriver' => 'mysqli',
    'db_debug' => (ENVIRONMENT !== 'production'),
    // ... other settings
);

Note: In some cases, getenv function may not work. Use $_ENV as an alternative.

Secutiry Tip

Never commit your .env file to version control. Add it to .gitignore

Conclusion

Now your CodeIgniter 3 app can securely use environment variables just like modern frameworks. This keeps your config clean, safe, and easy to manage across environments.

Implementing JWT Authentication in CodeIgniter 3

Learn how to implement secure JWT authentication in CodeIgniter 3. Step-by-step guide for token generation, validation, and integration.

Securing your mobile API is critical in modern applications. In this guide, we’ll walk through how to implement JWT (JSON Web Token) based authentication in CodeIgniter 3, including access token and refresh token support for long-lived sessions.

Overview of JWT Auth Flow

Here’s the standard flow:

  1. User logs in → server returns an access token and a refresh token.
  2. Mobile app uses the access token in the Authorization header for every request.
  3. When access token expires, the app sends the refresh token to get a new access token.

Prerequisites

  • CodeIgniter 3 installed
  • firebase/php-jwt JWT library via Composer
  • users table for authentication and user_tokens table for refresh tokens

Step 1: Install JWT Library

Use composer to install JWT library as follows:

composer require firebase/php-jwt

Step 2: Create JWT Helper Class

Create a JWT helper class file at application/libraries/Authorization_Token.php and add the following code to it:

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

class Authorization_Token {
    private $CI;
    private $token_key;

    public function __construct() {
        $this->CI =& get_instance();
        $this->token_key = 'YOUR_SECRET_KEY';
    }

    public function generateToken($user_data) {
        $issuedAt = time();
        $expirationTime = $issuedAt + 3600; // 1 hour
        $payload = [
            'iat' => $issuedAt,
            'exp' => $expirationTime,
            'data' => $user_data
        ];
        return JWT::encode($payload, $this->token_key, 'HS256');
    }

    public function validateToken() {
        $headers = apache_request_headers();
        if (!isset($headers['Authorization'])) return false;
        
        $token = str_replace('Bearer ', '', $headers['Authorization']);
        try {
            $decoded = JWT::decode($token, new Key($this->token_key, 'HS256'));
            return (array) $decoded->data;
        } catch (Exception $e) {
            return false;
        }
    }
}

Step 3: Create Login API

Create a user_tokens table for storing refresh tokens.

CREATE TABLE user_tokens (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    refresh_token VARCHAR(255) NOT NULL,
    expires_at DATETIME NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

Create a login API file anywhere inside app/controllers folder and add the following content inside it.

class Auth extends CI_Controller {
    public function login_post()
    {
        $email = $this->post('email');
        $password = $this->post('password');

        $user = $this->db->get_where('users', ['email' => $email])->row();

        if (!$user || !password_verify($password, $user->password)) {
            return $this->response(['status' => false, 'message' => 'Invalid credentials'], 401);
        }

        $this->load->library('Authorization_Token', null, 'authToken');
        $access_token = $this->authToken->generateToken(['id' => $user->id, 'email' => $user->email]);

        $refresh_token = bin2hex(random_bytes(64));
        $this->db->insert('user_tokens', [
            'user_id' => $user->id,
            'refresh_token' => $refresh_token,
            'expires_at' => date('Y-m-d H:i:s', strtotime('+30 days'))
        ]);

        return $this->response([
            'status' => true,
            'access_token' => $access_token,
            'refresh_token' => $refresh_token,
        ], 200);
    }
}

Step 4: Protect API Routes

Create a base controller file BaseApi_Controller.php inside app/controllers folder. Add the following code to base controller file.

class BaseApi_Controller extends REST_Controller
{
    public $user_data;

    public function __construct()
    {
        parent::__construct();
        $this->load->library('Authorization_Token', null, 'authToken');
        $user_data = $this->authToken->validateToken();

        if (!$user_data) {
            $this->response([
                'status' => false,
                'message' => 'Access token expired',
                'token_expired' => true
            ], 401);
            exit;
        }

        $this->user_data = $user_data;
    }
}

This file handles token validations for all requests. But, it will not automatically intercept all requests. So, all your secure API files need to extend this BaseApi_Controller.

class Orders extends Authenticated_Controller {
    public function list_get() {
        $user_id = $this->user_data['id'];
        $orders = $this->db->get_where('orders', ['user_id' => $user_id])->result();

        $this->output
            ->set_content_type('application/json')
            ->set_output(json_encode($orders));
    }
}

Step 5: Token Refresh

Create new api file AuthController.php for refresh token and add the following code in it.

class Auth extends CI_Controller {
    public function refresh_token_post()
    {
        $refresh_token = $this->post('refresh_token');

        $token_data = $this->db->get_where('user_tokens', [
            'refresh_token' => $refresh_token
        ])->row();

        if (!$token_data || strtotime($token_data->expires_at) < time()) {
            return $this->response([
                'status' => false,
                'message' => 'Invalid or expired refresh token'
            ], REST_Controller::HTTP_UNAUTHORIZED);
        }

        // Generate new access token
        $this->load->library('Authorization_Token', null, 'authToken');
        $access_token = $this->authToken->generateToken([
            'id' => $token_data->user_id,
            'email' => 'user@email.com' // Fetch if needed
        ]);

        return $this->response([
            'status' => true,
            'access_token' => $access_token,
            'expires_in' => 900
        ], REST_Controller::HTTP_OK);
    }
}

Summary

  • JWT access tokens: short-lived (e.g., 15 minutes)
  • Refresh tokens: long-lived (e.g., 30 days), stored securely
  • On access token expiry: client uses refresh token to get a new one
  • REST_Controller is used to simplify JSON responses in CodeIgniter 3

Final Thoughts

Implementing access and refresh tokens properly ensures secure and scalable mobile API sessions. Using CodeIgniter 3 with JWT and refresh tokens gives you full control over session lifecycle, security, and logout behavior.

Access shell with SSH on cPanel server from Linux

Discover an effective way to set PostgreSQL schemas using PHP PDO when the SET search_path approach fails. Learn best practices for schema-based architecture.

Some of the important server related problems will be solved only using shell access to the server. To access the cPanel server shell using SSH, there must be an SSH client installed on PC. Most of the Linux distros include SSH client software by default. If it is not installed, then it can be easily installed with following commands,

For Ubuntu: apt-get install openssh-client
For CentOS: yum install openssh-clients

After installation, follow these steps to access the cPanel shell with SSH from Linux:

  1. Login to cPanel and go to Security > SSH/Shell Access to generate SSH key pair.
  2. Click Manage SSH Keys > Generate a New Key. You should use a password to protect the key. You will be asked the password each time you use the key.
  3. In Public Keys section click ‘Manage Authorization’ and ‘Authorize’
  4. In Private Keys section click, Vew/Download then download the key (id_dsa or id_rsa) to your PC.
  5. Save it to ~/.ssh directory on your Linux machine under a meaningful name to not overwrite your existing keys for example id_dsa.myjavahost
  6. Now make sure permissions are correct on the key (one-time task) and connect:
    mypc:~$ chmod 600 .ssh/id_dsa
    mypc:~$ ssh -p1033 -i .ssh/id_dsa yourusername@yourservername
    Enter passphrase for key '.ssh/id_dsa':
  1. Provide the password for the key, set up in step #2

You should be logged in by now.