Ilmu Coding Ilmucoding.com - Merupakan situs yang membantu Anda belajar coding lebih mudah, nyaman, interaktif dan profesional. Belajar sekarang di ilmu coding. GRATIS

Tutorial Auth Codeigniter 4 Menggunakan JWT

6 min read

Tutorial Codeigniter 4 Auth with JWT - Ilmu Coding

Halo spark, pada tutorial kali ini saya akan membahas auth / authentication seperti login dan register pada Codeigniter 4 / CI4 menggunakan JWT.

Saat tutorial ini ditulis, Codeigniter 4 baru beberapa bulan yang lalu rilis versi stabilnya. Jadi, belum ada yang membahas tutorial Authentication Codeigniter 4 menggunakan JWT ini.

So, di sini saya akan jelaskan sedetail mungkin dan di akhir artikel, Anda bisa download source code yang sudah saya siapkan.

… tapi sebelum Anda download via Github. Ada baiknya untuk membaca penjelasannya di artikel ini terlebih dahulu.

Baca Juga: Tutorial Codeigniter 4 untuk Pemula

Siap?

Let’s go!

Apa Itu JWT?

Menurut beberapa referensi yang saya baca, JWT atau JSON Web Token (JWT) merupakan standar terbuka (RFC 7519) yang mendefinisikan cara yang ringkas dan mandiri untuk mentransmisikan informasi antar pihak secara aman sebagai objek JSON.

Informasi ini dapat diverifikasi dan dipercaya karena ditandatangani secara digital.

JWT dapat ditandatangani menggunakan kunci rahasia / token (dengan algoritma HMAC) atau pasangan public key / private key menggunakan RSA atau ECDSA.

Jadi, JWT dapat kita gunakan untuk menangani Auth karena fitur keamanan yang ditawarkannya. Apalagi jika sudah menyangkut pertukaran data antar pihak (mobile x web). Maka, posisi JWT menjadi amat penting.

Cara Menggunakan JWT di Codeigniter 4 untuk Kepentingan Auth

Oke, jika memang Anda sangat membutuhkan tutorial Auth menggunakan JWT di Codeigniter 4, kita akan memulainya dari step yang paling dasar.

Step 1 – Install Codeigniter 4

Cara pertama sudah barang tentu menyangkut install Codeigniter 4. Silahkan baca tutorial cara install Codeigniter 4 jika Anda belum membacanya.

Rekomendasi: Cara Install Codeigniter 4

Step 2 – Konfigurasi Database

Pertama, silahkan buat database baru dan beri nama ci4_auth_jwt.

Kedua, Rename file env menjadi .env (tambahkan titiknya).

Ketiga, cari kode berikut ini:

# CI_ENVIRONMENT = production

Ubah menjadi:

CI_ENVIRONMENT = development

Keempat, atur konfigurasi database dengan cara memodifikasi file .env menjadi:

database.default.hostname = localhost
database.default.database = ci4_auth_jwt
database.default.username = root
database.default.password = 
database.default.DBDriver = MySQLi

Pada kode tersebut, saya memberikan nama database, username dan password sesuai yang saya buat di web server.

Step 3 – Buat Table Users

Anda bisa menggunakan perintah di bawah ini untuk membuat file create table users:

php spark migrate:create users

Setelah itu, jangan lupa untuk memodifikasi filenya pada direktori app/Database/Migrations/*******_users.php.

Silahkan isi dengan kode berikut ini:

<?php namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Users extends Migration
{
	public function up()
	{
		$this->forge->addField([
			'id' => [
				'type' => 'INT',
				'constraint' => 11,
				'auto_increment' => TRUE
			],
			'first_name' => [
				'type' => 'VARCHAR',
				'constraint' => 100
			],
			'last_name' => [
				'type' => 'VARCHAR',
				'constraint' => 100
			],
			'email' => [
				'type' => 'VARCHAR',
				'constraint' => 100
			],
			'password' => [
				'type' => 'VARCHAR',
				'constraint' => 100
			]
		]);
		$this->forge->addKey('id');
		$this->forge->createTable('users');
	}

	public function down()
	{
		//
	}
}

… dan untuk migrate script table yang kita buat berada di database, silahkan ketik perintah berikut ini:

php spark migrate

Jika berhasil, di database kita akan memiiki table users. Silahkan cek ya.

Step 4 – Clone Package Firebase/JWT

Bagian ini sama sekali tidak boleh terlewat ya … Ini sangat penting. Jadi, silahkan kunjungi dulu link Github Firebase/JWT ini.

Kemudian masuk ke path ThirdParty dengan cara cd ThirdParty.

Jika sudah clone file dengan perintah berikut ini:

git clone https://github.com/firebase/php-jwt.git

Step 5 – Konfigurasi Package Firebase JWT

Setelah berhasil clone dan simpan di folder ThirParty, sekarang saatnya kita mengatur konfigurasi aplikasi. So, silahkan perhatikan gambar berikut ini:

Structure Project

Coba perhatikan baik-baik, saat pertama kali clone project Firebase/JWT, Anda akan mendapati file BeforeValidException.php, ExpiredException.php, JWK.php, JWT.php dan SignatureInvalidException.php berada di dalam folder src.

Namun pada tutorial kali ini, saya meng-cut semua file yang saya sebutkan di atas untuk menju ke barisan utama (di luar src tapi di dalam folder JWT).

Jika sudah, sekarang silahkan buka file Autoload.php pada direktori app/Config/Autoload.php.

Kemudian modifikasi bagian seperti pada gambar di bawah ini:

$psr4 = [
	'App'         => APPPATH,                // To ensure filters, etc still found,
	APP_NAMESPACE => APPPATH,                // For custom namespace
	'Config'      => APPPATH . 'Config',
	'Firebase'   => APPPATH . 'ThirdParty/Firebase',
];

Saya menambahkan baris ke 5 untuk memberikan inisialisasi name Firebase agar menuju ke ThirdParty/Firebase.

Step 6 – Membuat Model

Sekarang kita akan membuat Auth_model.php untuk menangani proses register dan cek login berdasarkan email.

Berikut kodenya:

<?php

namespace App\Models;

use CodeIgniter\Model;

class Auth_model extends Model{

    protected $table = "users";

    public function register($data)
    {
        $query = $this->db->table($this->table)->insert($data);
        return $query ? true : false;
    }

    public function cek_login($email)
    {
        $query = $this->table($this->table)
                ->where('email', $email)
                ->countAll();

        if($query >  0){
            $hasil = $this->table($this->table)
                    ->where('email', $email)
                    ->limit(1)
                    ->get()
                    ->getRowArray();
        } else {
            $hasil = array(); 
        }
        return $hasil;
    }
}

Simpan di direktori app/Models.

Step 7 – Membuat Controller

Sekarang saya akan membuat 2 controller yang berbeda. Pertama membuat controller Auth.php yang bertugas menangani login, register, dan generate token. Kedua, saya membuat controller Home.php sebagai halaman final yang bisa diakses jika user telah memasukan header (bearer Token) ke dalam request.

Berikut kode untuk Auth.php:

<?php namespace App\Controllers;

use \Firebase\JWT\JWT;
use App\Models\Auth_model;
use CodeIgniter\RESTful\ResourceController;

class Auth extends ResourceController
{
	public function __construct()
	{
		$this->auth = new Auth_model();
	}

	public function privateKey()
	{
		$privateKey = <<<EOD
			-----BEGIN RSA PRIVATE KEY-----
			MIICXAIBAAKBgQC8kGa1pSjbSYZVebtTRBLxBz5H4i2p/llLCrEeQhta5kaQu/Rn
			vuER4W8oDH3+3iuIYW4VQAzyqFpwuzjkDI+17t5t0tyazyZ8JXw+KgXTxldMPEL9
			5+qVhgXvwtihXC1c5oGbRlEDvDF6Sa53rcFVsYJ4ehde/zUxo6UvS7UrBQIDAQAB
			AoGAb/MXV46XxCFRxNuB8LyAtmLDgi/xRnTAlMHjSACddwkyKem8//8eZtw9fzxz
			bWZ/1/doQOuHBGYZU8aDzzj59FZ78dyzNFoF91hbvZKkg+6wGyd/LrGVEB+Xre0J
			Nil0GReM2AHDNZUYRv+HYJPIOrB0CRczLQsgFJ8K6aAD6F0CQQDzbpjYdx10qgK1
			cP59UHiHjPZYC0loEsk7s+hUmT3QHerAQJMZWC11Qrn2N+ybwwNblDKv+s5qgMQ5
			5tNoQ9IfAkEAxkyffU6ythpg/H0Ixe1I2rd0GbF05biIzO/i77Det3n4YsJVlDck
			ZkcvY3SK2iRIL4c9yY6hlIhs+K9wXTtGWwJBAO9Dskl48mO7woPR9uD22jDpNSwe
			k90OMepTjzSvlhjbfuPN1IdhqvSJTDychRwn1kIJ7LQZgQ8fVz9OCFZ/6qMCQGOb
			qaGwHmUK6xzpUbbacnYrIM6nLSkXgOAwv7XXCojvY614ILTK3iXiLBOxPu5Eu13k
			eUz9sHyD6vkgZzjtxXECQAkp4Xerf5TGfQXGXhxIX52yH+N2LtujCdkQZjXAsGdm
			B2zNzvrlgRmgBrklMTrMYgm1NPcW+bRLGcwgW2PTvNM=
			-----END RSA PRIVATE KEY-----
			EOD;
		return $privateKey;
	}

	public function register()
	{
		$firstname 	= $this->request->getPost('first_name');
		$lastname 	= $this->request->getPost('last_name');
		$email 		= $this->request->getPost('email');
		$password 	= $this->request->getPost('password');

		$password_hash = password_hash($password, PASSWORD_BCRYPT);

		$data = json_decode(file_get_contents("php://input"));

		$dataRegister = [
			'first_name' => $firstname,
			'last_name' => $lastname,
			'email' => $email,
			'password' => $password_hash
		];

		$register = $this->auth->register($dataRegister);

		if($register == true){
			$output = [
				'status' => 200,
				'message' => 'Berhasil register'
			];
    		return $this->respond($output, 200);
		} else {
			$output = [
				'status' => 400,
				'message' => 'Gagal register'
			];
    		return $this->respond($output, 400);
		}
	}

	public function login()
	{
		$email 		= $this->request->getPost('email');
		$password 	= $this->request->getPost('password');

		$cek_login = $this->auth->cek_login($email);

		// var_dump($cek_login['password']);

		if(password_verify($password, $cek_login['password']))
		{
			$secret_key = $this->privateKey();
			$issuer_claim = "THE_CLAIM"; // this can be the servername. Example: https://domain.com
			$audience_claim = "THE_AUDIENCE";
			$issuedat_claim = time(); // issued at
			$notbefore_claim = $issuedat_claim + 10; //not before in seconds
			$expire_claim = $issuedat_claim + 3600; // expire time in seconds
			$token = array(
				"iss" => $issuer_claim,
				"aud" => $audience_claim,
				"iat" => $issuedat_claim,
				"nbf" => $notbefore_claim,
				"exp" => $expire_claim,
				"data" => array(
					"id" => $cek_login['id'],
					"firstname" => $cek_login['first_name'],
					"lastname" => $cek_login['last_name'],
					"email" => $cek_login['email']
				)
			);

			$token = JWT::encode($token, $secret_key);

			$output = [
				'status' => 200,
				'message' => 'Berhasil login',
				"token" => $token,
                "email" => $email,
                "expireAt" => $expire_claim
			];
			return $this->respond($output, 200);
		} else {
			$output = [
				'status' => 401,
				'message' => 'Login failed',
				"password" => $password
			];
			return $this->respond($output, 401);
		}
	}

}

Kemudian pada Home.php, ini kodenya:

<?php namespace App\Controllers;

// Panggil JWT
use \Firebase\JWT\JWT;
// panggil class Auht
use App\Controllers\Auth;
// panggil restful api codeigniter 4
use CodeIgniter\RESTful\ResourceController;

header("Access-Control-Allow-Origin: * ");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

class Home extends ResourceController
{

	public function __construct()
	{
        // inisialisasi class Auth dengan $this->protect
        $this->protect = new Auth();
	}

	public function index()
	{
        // ambil dari controller auth function public private key
        $secret_key = $this->protect->privateKey();

		$token = null;

		$authHeader = $this->request->getServer('HTTP_AUTHORIZATION');

		$arr = explode(" ", $authHeader);

		$token = $arr[1];

		if($token){

			try {
		
				$decoded = JWT::decode($token, $secret_key, array('HS256'));
		
				// Access is granted. Add code of the operation here 
                if($decoded){
                    // response true
                    $output = [
                        'message' => 'Access granted'
                    ];
                    return $this->respond($output, 200);
                }
				
		
			} catch (\Exception $e){

				$output = [
					'message' => 'Access denied',
					"error" => $e->getMessage()
				];
		
				return $this->respond($output, 401);
			}
		}
	}

}

Bingung?

Awalnya saya juga begitu. Tapi sekarang kita akan memahaminya dulu sebelum melakukan testing.

Pertama dari Auth.php dan kita mulai dari baris kode ini:

use \Firebase\JWT\JWT;
use App\Models\Auth_model;

Buat apa kode ini?

Baris pertama tujuannya untuk memanggil package JWT yang sebelumnya telah kita inisialisasi dengan nama Firebase. Sedangkan baris kedua tidak lain untuk memanggil model Auth_model.php.

Kemudian pada baris kode berikut:

public function privateKey() 

Kok privateKey diberikan public?

Sebenernya biar privateKey ini bisa digunakan pada controller lain. Jadi, saya tidak perlu membuat function privateKey lagi di controller lain. Cukup panggil saja function ini di controller lainnya.

Kemudian pada function register seperti function store pada umumnya. Tidak ada yang berhubungan dengan token.

Nah, baru pada function login terdapat hubungan dengan JWT. Jadi setiap user melakukan login ia akan diberikan token yang dapat digunakan untuk mengakses halaman Home.php. Tanpa token tersebut, user tidak akan bisa mengakses halaman Home.php ke depannya.

… dan pada Home.php saya memberikan proses pengecekan token cocok atau tidak untuk menentukan apakah user tersebut diberikan akses atau tidak. Itu semua tergantung token yang ia sisipkan pada bearer token. Anda bisa mengubah proses output pada baris ke ? untuk diisi dengan akses API yang Anda buat.

Step 8 – Compiling dan Testing

Mari kita jalankan project dengan perintah berikut ini:

php spark serve

Lalu, buka Postman dan silahkan ketik URL berikut untuk melakukan register terlebih dahulu dengan method POST:

localhost:8080/auth/register

Perhatikan gambar berikut untuk melihat hasilnya:

Tutorial Auth Codeigniter 4 Menggunakan JWT - Register Success

Kemudian cobalah melakukan login dengan akun yang tadi sudah Anda register ke database dengan method POST.

localhost:8080/auth/login

Silahkan masukan email dan password yang telah Anda register.

Jika berjalan dengan lancar, berikut hasilnya:

Tutorial Auth Codeigniter 4 Menggunakan JWT - Login Success

Catat tokennya ya. Token ini sangat berguna agar bisa mengakses halaman Home. Coba kita uji ya.

Halaman home dengan diisi token pada saat kita melalukan login (hasilnya akses diberikan):

Tutorial Auth Codeigniter 4 Menggunakan JWT - Home Success

Sekarang, kita akan coba membuat kesalahan pada input token. Misalnya saya hapus salah satu huruf di dalam token untuk menampilkan pesan errornya atau dengan cara tanpa mamasukan token.

Oke, saya akan mencoba menghapus salah satu huruf di dalam token.

Apa yang akan terjadi? Ini dia hasilnya:

Home Gagal

Yaps, saya hanya menghapus 1 huruf “e” di awal, hasilnya akses denied. Artinya kita tidak bisa mengakses API.

Penutup

Oke, Alhamdulillah telah selesai tutorial Auth Codeigniter 4 menggunakan JWT. Cukup panjang, namun itu ga masalah kalau kita semangat belajar.

Setuju?

Kalau setuju, saya akan kasih bonus source codenya.

Mau?

Silahkan clone / download melalui link Github di bawah ini:

Github Codeigniter 4 With JWT

Semoga tutorial ini bermanfaat. Silahkan share sebanyak-banyaknya ya.

Ilmu Coding Ilmucoding.com - Merupakan situs yang membantu Anda belajar coding lebih mudah, nyaman, interaktif dan profesional. Belajar sekarang di ilmu coding. GRATIS

27 Replies to “Tutorial Auth Codeigniter 4 Menggunakan JWT”

  1. Tutorialnya sangat menarik,saya punya usul dicombine dengan flutter login menggunakan session dari token CI nya

  2. Mas, saya taro private key di BaseController supaya bisa preload di seluruh controller bisa juga kan?
    kaya di CI3 itu MY_Controller

    1. JWT tidak menggunakan logout, Mas. Kita bisa atur berapa lama token tersebut exp. Sehingga auto login lagi jika waktu tokennya sudah exp.

  3. Awalnya saat login error :
    “message”: “Class ‘Firebase\\JWT\\JWT’ not found”,

    Setelah saya ubah di Autoload.php
    ‘Firebase\JWT’ => APPPATH . ‘ThirdParty/php-jwt’,

    Alhamdulilah berhasil.
    Thanks

    1. Di Ilmu Coding sudah ada tutorial CRUD RestFul API Codeigniter 4. Tingal pindahin functionnya ke dalam class Home pada tutorial ini saja. Selebihnya modifikasi.

  4. Apa tidak semacam middleware di CI 4? apa kita harus terus2 melakukan if($token) ?
    Nice article BTW, Thanks!

    1. Kalau di CI3, saya bikin function sendiri untuk cek status login di system/core/Controller.php

      Pemanggilannya tinggal dari contructor setiap controller. Jadi, setiap function nggak perlu ada if($cek_login) lagi.

      Kalau di CI4, saya sudah membuatkan tutorialnya di https://ilmucoding.com/middleware-filters-codeigniter-4/

      Sudah ada bagian filter di tutorial tersebut.

  5. Assalamu’alalikum…
    izin bertanya cara buat email activation menggunakan package bawaan dari myth auth lonniezel gimana ya mas, terima kasih!

  6. Selamat pagi mas, saya mau nanya.

    CodeIgniter CLI Tool – Version 4.0.2 – Server-Time: 2020-06-16 21:57:34pm

    Running all new migrations…

    No such file or directory
    /Applications/MAMP/htdocs/codeigniter-4-auth-with-jwt-master/system/Database/MySQLi/Connection.php – 225

    problem berikut ini gimana yaa mas?

    1. Coba /Applications/MAMP/htdocs/ci4/system/Database/MySQLi/Connection.php
      line 106
      ubah
      $socket = null;
      menjadi
      $socket = ‘/Applications/MAMP/tmp/mysql/mysql.sock’;
      trus jalankan migrate ulang

  7. Sangat membantu, tapi bagaimana menerapkan sebagai midleware biar bisa dipakai berulang kali jadi hanya di filter aja dipanggil.
    Kalai boleh buatkan tutorial nya om
    Thanks

    1. Coba pakai fitur grouping di routenya, Mas. Jadi cukup sekali panggil filternya, nanti route lain tinggal ngikut…

  8. Mantab mas ilmunya, sangat membantu tugas UAS saya, terima kasih banyak. Sukses selalu mas hehe

  9. mas mau tanya..
    untuk menyimpan token hasil login di localstorage, sedangkan kita pakai PHP (codeigniter) gimana ya caranya?

    saya ingin membuat login page pure menggunakan jwt / tidak menggunakan session sama sekali, namun kan yang namanya php itu serverside, sedangkan kalau jwt, kita simpan di device user

    1. Kalau di device, tetap simpan token di shared preferences. Kalau di serverside tetap pakai session.

    1. pas di sini:

      $issuedat_claim = time(); // issued at
      $notbefore_claim = $issuedat_claim + 10; //not before in seconds
      $expire_claim = $issuedat_claim + 3600;
      ...
      "exp" => $expire_claim,
      
      1. terdapat di folder mana ya mas? hehehe saya masih belajar dan belum tau cara menggantinya.
        coba saya carinya dulu.

Leave a Reply

Your email address will not be published. Required fields are marked *

Jika terbantu dengan artikel ini, silahkan share, beri komentar dan "klik" 1 kali pada iklan ya.