Tutorial Laravel: Implementasi JWT untuk RESTful API

Thumbnail Tutorial Laravel: Implementasi JWT untuk RESTful API

Implementasi JWT di Laravel 11 untuk keamanan API dapat diimplementasikan dengan mudah. Sedikit informasi pembuka, JWT adalah singkatan dari JSON Web Token yang merupakan jenis metode autentikasi dengan memanfaatkan token dalam batas waktu tertentu, sehingga autentikasi yang menggunakan JWT akan bersifat stateless atau tidak menyimpan sesi pada sisi server.

Baca juga: Tutorial Laravel: CRUD RESTful API Sederhana.

Berikut adalah langkah-langkah implementasi JWT di Laravel.

1. Menyiapkan Proyek Laravel

Pertama, buatlah proyeknya terlebih dahulu. Saya akan membuat proyek dengan nama folder laravel-jwt.

composer create-project laravel/laravel laravel-jwt

Bukalah proyek Laravel yang telah dibuat sebelumnya di code editor kesayangan masing-masing. Kemudian, buka file .env dan sesuaikan beberapa nilai yang berkaitan dengan konfigurasi database. Saya menggunakan PostgreSQL dan konfigurasi milik saya seperti di bawah ini.

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=latihan
DB_USERNAME=postgres
DB_PASSWORD=root

Karena JWT adalah metode autentikasi, maka diperlukan akun pengguna yang akan digunakan untuk login atau generate token. Saya menggunakan akun user default yang telah disediakan oleh Laravel sehingga tidak perlu membuat migration dan menyiapkan model dari awal. Akun default tersebut dapat dilihat pada file DatabaseSeeder.php, nantinya akun untuk pengujian ini akan memiliki email "test@example.com" dan password-nya "password". Untuk membuat akun pengguna tersebut jalankan perintah di bawah, namun perlu diperhatikan bahwa perintah di bawah ini akan mereset semua tabel yang ada pada database-nya.

php artisan migrate:fresh --seed

Silahkan cek tabel users di database, seharusnya suda ada satu baris yang berisi data pengguna yang sudah dijelaskan sebelumnya.

Berikutnya adalah memunculkan file api.php dan memasang package tymon/jwt-auth untuk memulai implementasi JWT ke proyek Laravel. Jalankan perintah berikut di terminal, pastikan sudah mengarah ke root direktori proyek Laravelnya.

php artisan install:api

Apabila muncul pertanyaan untuk menjalankan migrasi, pilih saja no. Karena, kita sudah melakukan migrasi pada tahap sebelumnya.

Pastikan bahwa file api.php telah tersedia pada folder routes dan muncul routing yang mengarah pada file tersebut di file app.php pada folder bootstrap.

2. Konfigurasi JWT

Berikutnya mari pasang package untuk JWT. Jalankan beberapa perintah berikut satu per satu:

composer require tymon/jwt-auth
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
php artisan jwt:secret

Untuk memastikan bahwa JWT telah dipasang dengan baik, buka file .env dan seharusnya akan muncul key bernama JWT_SECRET di baris terakhir. Nilai JWT_SECRET tersebut perlu dijaga, karena merupakan kunci rahasia yang digunakan untuk menghasilkan dan mevalidasi JSON Web Token di Laravel. Kunci rahasia tersebut sangat penting dalam proses autentikasi berbasis token karena digunakan untuk encode payload JWT yang berisi informasi pengguna pemilik token dan validasi token setiap ada permintaan masuk.

Modifikasi model User atau file User.php yang berada pada folder Models menjadi seperti berikut:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use HasFactory, Notifiable;
    
    protected $fillable = ['name', 'email', 'password'];
    protected $hidden = ['password', 'remember_token'];
    
    protected function casts(): array
    {
    
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
    
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }
    
    public function getJWTCustomClaims()
    {
        return [];
    }
}

Sesuaikan beberapa nilai yang ada pada file auth.php di folder config.

'defaults' => [
    'guard' => env('AUTH_GUARD', 'api'),
    'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
],
…
'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

3. Membuat Controller, Middleware, dan Route untuk Autentikasi

Sekarang mari buat file UserController.php untuk menangani proses autentikasi (login) atau mendapatkan akes token JWT, invalidate akses token (logout), dan menampilkan data pengguna jika sudah terautentikasi (token sah dan aktif). Jalankan perintah di bawah ini untuk membuat controller.

php artisan make:controller UserController

Buka controller yang baru saja dibuat dan isikan dengan kode seperti berikut:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;

class UserController extends Controller
{
    public function login(Request $request) {
        $credentials = $request->only('email', 'password');
        $token = auth()->setTTL(60)->attempt($credentials);
        
        if ($token) {
            return response()->json([
                'status' => 'success',
                'data' => [
                    'access_token' => $token,
                    'token_type' => 'bearer',
                    'expires_in' => auth()->factory()->getTTL() . ' minutes',
                ],
            ], Response::HTTP_CREATED);
        }
        
        return response()->json([
            'status' => 'fail',
            'message' => 'Login failed'
        ], Response::HTTP_UNAUTHORIZED);
    }
    
    public function logout() {
        auth()->logout(true);
        
        return response()->json([
            'status' => 'success',
            'message' => 'Successfully logged out'
        ]);
    }
    
    public function me() {
        return response()->json([
            'status' => 'success',
            'data' => auth()->user(),
        ]);
    }
}

Fungsi setTTL() digunakan untuk mengatur waktu kadaluarsa token dalam satuan menit yang dihitung sejak pengguna mendapatkan token.

Diperlukan juga middleware untuk memastikan bahwa nantinya fungsi logout() dan me() hanya dapat diakses oleh pengguna yang sudah lolos autentikasi. Saya akan membuat middleware tersebut bernama AuthJWT.

php artisan make:middleware AuthJWT

Kemudian buka file AuthJWT.php yang baru saja dibuat pada folder Middleware dan ganti isinya dengan kode berikut.

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use Tymon\JWTAuth\Facades\JWTAuth;

class AuthJWT
{
    public function handle(Request $request, Closure $next): Response
    {
        if (auth()->check() and JWTAuth::parseToken()->authenticate()) {
            return $next($request);
        }
        
        return response()->json([
            'status' => 'fail',
            'error' => 'Token',
            'message' =>'Access token could not be found'
        ], Response::HTTP_FORBIDDEN);
    }
}

Ganti juga kode pada file api.php menjadi seperti di bawah ini.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
use App\Http\Middleware\AuthJWT;

Route::controller(UserController::class)
    ->middleware(AuthJWT::class)
    ->group(function () {
        Route::post('/authentications', 'login')->withoutMiddleware(AuthJWT::class);
        Route::delete('/authentications', 'logout');
        Route::get('/users/me', 'me');
    });

Jalankan proyek Laravel dengan menggunakan perintah:

php artisan serve

4. Pengujian dengan Menggunakan Postman

Saatnya melakukan pengujian, pada tahap ini saya menggunakan aplikasi Postman untuk menguji API yang telah menggunakan metode autentikasi JWT.

Pengujian Login atau Generate Akses Token

Pada body isikan email dan password dalam format JSON seperti pada gambar di atas dan gunakan method POST karena akan menjalankan endpoint untuk login, nah jika berhasil API akan memberikan respons yang berisi akses token.

Copy akses token yang telah didapat, karena akan diperlukan pada pengujian berikutnya.

Pengujian Endpoint Get Data Pengguna yang Tela Terautentikasi

Pengujian pada gambar di atas adalah menampilkan data pengguna yang telah lolos autentikasi. Endpoint ini memerlukan akses token yang telah didapat pada pengujian sebelumnya, untuk menggunakan akses token tersebut pergi ke tab menu Auth dan pilih Auth Type dengan nilai Bearer Token, kemudian paste pada kolom Token. Gunakan method GET dan send. Kemudian coba send tanpa menggunakan token atau setelah logout.

Pengujian Logout atau invalidate akses token

Pada pengujian untuk logout juga diperlukan akses token.

Kesimpulan

Demikianlah langkah-langkah implementasi JWT di Laravel menggunakan package tymon/jwt-auth. Autentikasi menggunakan JWT memungkinkan aplikasi untuk melakukan autentikasi tanpa menyimpan sesi di server, bisa dipakai pada berbagai platform dan berbagai bahasa pemrograman. Penggunaan JWT dapat dikombinasikan dengan OAuth2.0 dan memungkinkan pengembangan sistem SSO.