Tutorial Login dan Register Menggunakan JWT pada CodeIgniter 4

Tutorial Login dan Register Menggunakan JWT pada CodeIgniter 4

Pada tutorial ini Anda akan belajar bagaimana membuat login, register, dan memproteksi endpoint atau resources dengan JSON Web Token menggunakan CodeIgniter 4.

(Step-by-Step)

Mari kita mulai.

Tonton video tutorial web berkualitas GRATIS di channel youtube saya:

Klik Disini.!

 

Step #1. Install CodeIgniter 4

Untuk menginstal CodeIgniter 4 dapat dilakukan dengan 2 cara yaitu: Instalasi manual dan Instalasi menggunakan composer.

Pada tutorial ini, saya akan menggunakan composer.

Jika Anda belum memiliki composer, silahkan kunjungi URL berikut untuk mendownload composer, kemudian install di komputer Anda:

https://getcomposer.org/

Setelah composer terinstall di komputer Anda dan untuk memastikan composer terinstall dengan baik di komputer Anda, buka terminal atau Command Prompt (CMD).

Kemudian ketikan perintah berikut:

composer -v

Seperti gambar berikut:

composer

Setelah composer terinstal dengan baik di komputer Anda, kemudian Anda dapat membuat project CodeIgniter 4 menggunakan composer.

Buat sebuah folder baru di web server Anda, disini saya beri nama “jwt-app”.

Jika Anda menggunakan WAMPSERVER, buat di folder:

C:/wamp64/www

Jika Anda menggunakan XAMPP, buat di folder:

C:/xampp/htdocs

Pada tutorial ini, saya menggunakan XAMPP.

Kemudian buka folder “jwt-app” tersebut menggunakan Code Editor, disini saya menggunakan Visual Studio Code.

Setelah itu, integrasikan dengan terminal pada Visual Studio Code.

Kemudian ketikan perintah berikut pada terminal untuk membuat project CodeIgniter 4:

composer create-project codeigniter4/appstarter .

Perintah diatas akan membuat project CodeIgniter baru pada folder “jwt-app”.

Tunggu sampai proses instalasinya selesai.

 

Step #2. Buat Database

Buat sebuah database baru pada MySQL, Anda dapat menggunakan tools seperti SQLyog, PHPMyAdmin atau sejenisnya.

Disini saya membuat database dengan nama “jsonwebtoken”.

Jika Anda membuat database dengan nama yang sama itu lebih baik.

Untuk  membuat database pada MySQL, dapat dilakukan dengan mengeksekusi query berikut:

CREATE DATABASE jsonwebtoken;

Perintah SQL diatas akan membuat sebuah database dengan nama “jsonwebtoken”.

Selanjutnya, buat koneksi antara database dengan project CodeIgniter.

Temukan file env pada root project, kemudian rename (ganti nama) menjadi .env dan open file tersebut.

Kemudian temukan kode berikut:

# database.default.hostname = localhost
# database.default.database = ci4
# database.default.username = root
# database.default.password = root
# database.default.DBDriver = MySQLi

Ubah menjadi seperti berikut:

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

 

Step #3. Migrations

Pada tutorial ini, saya akan menggunakan fitur migration pada CodeIgniter 4 untuk pembuatan table.

Ketikan perintah berikut pada Terminal/Command Prompt:

php spark make:migration Users

Kemudian Enter, maka CodeIgniter akan membuat sebuah file berinisial “Users” pada folder “app/Database/Migrations”.

Seperti gambar berikut:

migrations

Buka file tersebut, kemudian ketikan kode berikut:

<?php

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

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

    public function down()
    {
        //
    }
}

Pada kode diatas, kita hanya menambahkan kode pada function up().

Function up, berfungsi untuk membuat table di database dengan field yang ditetapkan.

Pada kasus diatas, kita membuat sebuah table dengan nama “users” dengan field id, email, dan password beserta type data dan atribut lainnya.

Jika Anda tidak terbiasa dengan migration, mungkin terlihat rumit, tapi sebenarnya tidak.

Selanjutnya, ketikan perintah berikut pada Terminal/Command Prompt:

php spark migrate

Kemudian Enter, maka CodeIgniter akan otomatis membuat table “users” dengan field: id, email, dan password di dalam database “jsonwebtoken”.

 

Step #4. Instalasi JSON Web Token (JWT)

Untuk menginstall JSON Web Token untuk PHP, jalankan perintah berikut pada terminal:

composer require firebase/php-jwt 

Maka composer akan menginstall JSON Web Token secara otomatis di project Anda.

Setelah instalasi selesai, pergi ke file “.env”. kemudian tambah variable secret key seperti berikut:

TOKEN_SECRET = cskhfuwt48wbfjn3i4utnjf38754hf3yfbjc93758thrjsnf83hcwn8437

Anda bebas membuat secret key-nya, semakin rumit lebih baik.

 

Step #5. Model

Buat sebuah file model dengan cara mengetikan perintah berikut pada terminal:

php spark make:model UserModel

Maka secara otomatis CodeIgniter akan membuat sebuah file model bernama “UserModel.php” di dalam folder “app/Models”.

Kemudian, open file tersebut dan ubah kodenya menjadi seperti berikut:

<?php

namespace App\Models;

use CodeIgniter\Model;

class UserModel extends Model
{
    protected $DBGroup              = 'default';
    protected $table                = 'users';
    protected $primaryKey           = 'id';
    protected $useAutoIncrement     = true;
    protected $insertID             = 0;
    protected $returnType           = 'array';
    protected $useSoftDeletes       = false;
    protected $protectFields        = true;
    protected $allowedFields        = ['email','password'];

    // Dates
    protected $useTimestamps        = false;
    protected $dateFormat           = 'datetime';
    protected $createdField         = 'created_at';
    protected $updatedField         = 'updated_at';
    protected $deletedField         = 'deleted_at';

    // Validation
    protected $validationRules      = [];
    protected $validationMessages   = [];
    protected $skipValidation       = false;
    protected $cleanValidationRules = true;

    // Callbacks
    protected $allowCallbacks       = true;
    protected $beforeInsert         = [];
    protected $afterInsert          = [];
    protected $beforeUpdate         = [];
    protected $afterUpdate          = [];
    protected $beforeFind           = [];
    protected $afterFind            = [];
    protected $beforeDelete         = [];
    protected $afterDelete          = [];
}

Pada kode di atas, kita hanya melakukan sedikit perubahan yaitu pada allowedFields.

 

Step #6. Controllers

Buat sebuah file controller dengan cara mengetikan perintah berikut pada terminal:

php spark make:controller Register --restful

Maka secara otomatis CodeIgniter akan membuat sebuah file controller bernama “Register.php” di dalam folder “app/Controllers”.

Kemudian, open file tersebut dan ubah kodenya menjadi seperti berikut:

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\API\ResponseTrait;
use App\Models\UserModel;

class Register extends ResourceController
{
    /**
     * Return an array of resource objects, themselves in array format
     *
     * @return mixed
     */
    use ResponseTrait;
    public function index()
    {
        helper(['form']);
        $rules = [
            'email' => 'required|valid_email|is_unique[users.email]',
            'password' => 'required|min_length[6]',
            'confpassword' => 'matches[password]'
        ];
        if(!$this->validate($rules)) return $this->fail($this->validator->getErrors());
        $data = [
            'email'     => $this->request->getVar('email'),
            'password'  => password_hash($this->request->getVar('password'), PASSWORD_BCRYPT) 
        ];
        $model = new UserModel();
        $registered = $model->save($data);
        $this->respondCreated($registered);

    }

}

Controller tersebut berfungsi untuk register user baru.

Selanjutnya, buat file controller untuk login dengan menjalankan perintah berikut pada terminal:

php spark make:controller Login --restful

Maka secara otomatis CodeIgniter akan membuat sebuah file controller bernama “Login.php” di dalam folder “app/Controllers”.

Kemudian, open file Login.php tersebut dan ubah kodenya menjadi seperti berikut:

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\API\ResponseTrait;
use App\Models\UserModel;
use Firebase\JWT\JWT;

class Login extends ResourceController
{
    /**
     * Return an array of resource objects, themselves in array format
     *
     * @return mixed
     */
    use ResponseTrait;
    public function index()
    {
        helper(['form']);
        $rules = [
            'email' => 'required|valid_email',
            'password' => 'required|min_length[6]'
        ];
        if(!$this->validate($rules)) return $this->fail($this->validator->getErrors());
        $model = new UserModel();
        $user = $model->where("email", $this->request->getVar('email'))->first();
        if(!$user) return $this->failNotFound('Email Not Found');

        $verify = password_verify($this->request->getVar('password'), $user['password']);
        if(!$verify) return $this->fail('Wrong Password');

        $key = getenv('TOKEN_SECRET');
        $payload = array(
            "iat" => 1356999524,
            "nbf" => 1357000000,
            "uid" => $user['id'],
            "email" => $user['email']
        );

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

        return $this->respond($token);
    }
}

Kemudian, buat sebuah file controller lagi untuk mendapat current user login dengan menjalankan perintah berikut pada terminal:

php spark make:controller Me --restful

Maka secara otomatis CodeIgniter akan membuat sebuah file controller bernama “Me.php” di dalam folder “app/Controllers”.

Kemudian, open file Me.php tersebut dan ubah kodenya menjadi seperti berikut:

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;
use CodeIgniter\API\ResponseTrait;
use App\Models\UserModel;
use Firebase\JWT\JWT;

class Me extends ResourceController
{
    /**
     * Return an array of resource objects, themselves in array format
     *
     * @return mixed
     */
    use ResponseTrait;
    public function index()
    {
        $key = getenv('TOKEN_SECRET');
        $header = $this->request->getServer('HTTP_AUTHORIZATION');
        if(!$header) return $this->failUnauthorized('Token Required');
        $token = explode(' ', $header)[1];

        try {
            $decoded = JWT::decode($token, $key, ['HS256']);
            $response = [
                'id' => $decoded->uid,
                'email' => $decoded->email
            ];
            return $this->respond($response);
        } catch (\Throwable $th) {
            return $this->fail('Invalid Token');
        }
    }

}

 

Step #7. Filters

Buat sebuah file filter yang berfungsi untuk memproteksi end-point dari user yang tidak ter otentikasi.

Untuk membuat file filter, jalankan perintah berikut pada terminal:

php spark make:filter Auth

Maka secara otomatis CodeIgniter akan membuat sebuah file filter bernama “Auth.php” di dalam folder “app/Filters”.

Kemudian, open file Auth.php tersebut dan ubah kodenya menjadi seperti berikut:

<?php

namespace App\Filters;

use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Firebase\JWT\JWT;
use Config\Services;

class Auth implements FilterInterface
{
    /**
     * Do whatever processing this filter needs to do.
     * By default it should not return anything during
     * normal execution. However, when an abnormal state
     * is found, it should return an instance of
     * CodeIgniterHTTPResponse. If it does, script
     * execution will end and that Response will be
     * sent back to the client, allowing for error pages,
     * redirects, etc.
     *
     * @param RequestInterface $request
     * @param array|null       $arguments
     *
     * @return mixed
     */
    public function before(RequestInterface $request, $arguments = null)
    {
        $key = getenv('TOKEN_SECRET');
        $header = $request->getServer('HTTP_AUTHORIZATION');
        if(!$header) return Services::response()
                            ->setJSON(['msg' => 'Token Required'])
                            ->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED);
        $token = explode(' ', $header)[1];

        try {
            JWT::decode($token, $key, ['HS256']);
        } catch (\Throwable $th) {
            return Services::response()
                            ->setJSON(['msg' => 'Invalid Token'])
                            ->setStatusCode(ResponseInterface::HTTP_UNAUTHORIZED);
        }
    }

    /**
     * Allows After filters to inspect and modify the response
     * object as needed. This method does not allow any way
     * to stop execution of other after filters, short of
     * throwing an Exception or Error.
     *
     * @param RequestInterface  $request
     * @param ResponseInterface $response
     * @param array|null        $arguments
     *
     * @return mixed
     */
    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
        //
    }
}

Selanjutnya buka file “Filters.php” yang terdapat pada folder “app/Config”.

Kemudian temukan kode berikut:

public $aliases = [
        'csrf'     => CSRF::class,
        'toolbar'  => DebugToolbar::class,
        'honeypot' => Honeypot::class
    ];

Kemudian ubah menjadi seperti berikut:

public $aliases = [
        'csrf'     => CSRF::class,
        'toolbar'  => DebugToolbar::class,
        'honeypot' => Honeypot::class,
        'auth'     => App\Filters\Auth::class
    ];

Selanjutnya, lakukan sedikit konfigurasi pada file “Routes.php” yang terdapat pada folder “app/Config”.

Temukan kode berikut:

$routes->get('/', 'Home::index');

Kemudian ubah menjadi seperti berikut:

$routes->get('/', 'Home::index', ['filter' => 'auth']);
$routes->post('register', 'Register::index');
$routes->post('login', 'Login::index');

Pada kode diatas, kita memproteksi end-point home dengan filter “auth”.

Dengan kata lain, kita tidak dapat mengakses controller home tanpa akses token.

Jika Anda memilki banyak end-point yang ingin di proteksi, Anda hanya perlu menambahkan filter “auth” pada routes-nya seperti contoh diatas.

Selanjutnya, buat sebuah file filter lagi untuk CORS (Cross-Origin Resource Sharing) agar API kita dapat diakses dari luar domain.

Untuk membuat filter CORS, jalankan perintah berikut pada terminal:

php spark make:filter Cors

Maka secara otomatis CodeIgniter akan membuat sebuah file filter bernama “Cors.php” di dalam folder “app/Filters”.

Kemudian, open file Cors.php tersebut dan ubah kodenya menjadi seperti berikut:

<?php

namespace App\Filters;

use CodeIgniter\Filters\FilterInterface;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;

class Cors implements FilterInterface
{
    /**
     * Do whatever processing this filter needs to do.
     * By default it should not return anything during
     * normal execution. However, when an abnormal state
     * is found, it should return an instance of
     * CodeIgniterHTTPResponse. If it does, script
     * execution will end and that Response will be
     * sent back to the client, allowing for error pages,
     * redirects, etc.
     *
     * @param RequestInterface $request
     * @param array|null       $arguments
     *
     * @return mixed
     */
    public function before(RequestInterface $request, $arguments = null)
    {
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Allow-Headers: X-API-KEY, Origin,X-Requested-With, Content-Type, Accept, Access-Control-Requested-Method, Authorization");
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PATCH, PUT, DELETE");
        $method = $_SERVER['REQUEST_METHOD'];
        if($method == "OPTIONS"){
            die();
        }
    }

    /**
     * Allows After filters to inspect and modify the response
     * object as needed. This method does not allow any way
     * to stop execution of other after filters, short of
     * throwing an Exception or Error.
     *
     * @param RequestInterface  $request
     * @param ResponseInterface $response
     * @param array|null        $arguments
     *
     * @return mixed
     */
    public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
    {
        //
    }
}

Buka file “Filters.php” yang terdapat pada folder “app/Config”, kemudian tambah filter cors-nya seperti berikut:

public $aliases = [
        'csrf'     => CSRF::class,
        'toolbar'  => DebugToolbar::class,
        'honeypot' => Honeypot::class,
        'auth'     => App\Filters\Auth::class,
        'cors'     => App\Filters\Cors::class,
    ];

Selanjutnya definisikan “cors” pada public $globals seperti berikut:

public $globals = [
        'before' => [
            // 'honeypot',
            // 'csrf',
            'cors'
        ],
        'after'  => [
            //'toolbar',
            // 'honeypot',
        ],
    ];

 

Step #8. Testing

Untuk melakukan pengujian, jalankan project kita dengan mengetikan perintah berikut pada terminal:

php spark serve

Seperti gambar berikut:

spark serve

Pada tutorial kali ini saya akan menggunakan POSTMAN untuk melakukan pengujian.

Saya juga menyarankan Anda untuk menggunakan POSTMAN.

Anda dapat mendownload POSTMAN pada link berikut, dan install di komputer Anda:

https://www.postman.com/downloads/

Setelah POSTMAN terinstal di komputer Anda, buka POSTMAN untuk melakukan pengujian.

 

#1. Register

Ketikan URL berikut pada kolom URL Postman:

http://localhost:8080/register

Pilih method POST => Body => raw => JSON => masukkan datanya dalam format JSON, kemudian klik tombol Send, seperti gambar berikut:

register

Jika berjalan dengan baik, maka akan terlihat status: 201 Created seperti gambar diatas.

 

#2. Login

Ketikan URL berikut pada kolom URL Postman:

http://localhost:8080/login

Pilih method POST => Body => raw => JSON => masukkan data email dan password dalam format JSON, kemudian klik tombol Send, seperti gambar berikut:

login

Jika login berhasil, maka kita akan mendapatkan respon token seperti gambar diatas.

Kita bisa gunakan token tersebut untuk mengakses resources yang di proteksi.

 

#3. Get Current User Login

Ketikan URL berikut pada kolom URL Postman:

http://localhost:8080/me

Pilih method GET => Authorization => Bearer Token => copy dan paste-kan token sebelumnya pada field token, kemudian klik tombol Send, seperti gambar berikut:

me

Jika berjalan dengan baik, maka kita mendapat id dan email dari user login seperti gambar diatas.

 

#4. Access Protected Resources

Kita juga bisa mengakses resource yang di proteksi dengan memanfaatkan token tersebut.

Pada tutorial ini, kita proteksi route home. Dengan kata lain, kita tidak dapat mengakses home tanpa token.

Ketikan URL berikut pada kolom URL Postman:

http://localhost:8080

Pilih method GET => Authorization => Bearer Token => copy dan paste-kan token sebelumnya pada field token, kemudian klik tombol Send, seperti gambar berikut:

protected endpoint

Jika berjalan dengan baik, maka akan terlihat status: 200 Ok dan response html seperti gambar diatas.

Jika kita mengakses home tanpa token, maka akan terlihat status: 401 Unauthorized dan pesan “Token Required” seperti gambar berikut:

token required

Dan jika kita mengakses home dengan token yang salah, maka akan terlihat status: 401 Unauthorized dan pesan “Invalid Token” seperti gambar berikut:

invalid token

 

Kesimpulan:

Pembahasan kali ini adalah tentang bagaimana membuat login, register, dan memproteksi endpoint atau resources dengan JSON Web Token menggunakan CodeIgniter 4.

Jadi tunggu apalagi, let’s coding!

Download Source Code

Share:




LAINNYA UNTUK ANDA


Komentar (2)

Franky, 29 September 2021 07:45 - Reply

Undefined type 'FirebaseJWTJWT'. Di file Login Controller, adakah solusinya Mas?

M Fikri, 08 October 2021 15:27 - Reply

Jangan lupa instal JWT di Step #4.!

Leave a Comment