Cara Implementasi JWT Pada Laravel 9

Otentikasi token web JSON (JWT) digunakan untuk memverifikasi kepemilikan data JSON. JWT bukanlah enkripsi, melainkan menentukan apakah data dapat dipercaya karena kepemilikannya diverifikasi. JWT adalah standar terbuka (RFC 7519) yang memungkinkan informasi dikirimkan dengan aman antara dua pihak sebagai objek JSON. JWT ditandatangani secara digital menggunakan pasangan kunci publik/pribadi atau rahasia.

Pada artikel ini, kami akan mendemonstrasikan proses penerapan otentikasi JWT di Laravel 9. Kami juga akan meninjau beberapa fitur Laravel dan membandingkan JWT dengan paket otentikasi bawaan Laravel (Sanctum dan Passport).

Apa itu Laravel ?

Laravel adalah framework web PHP sumber terbuka gratis yang dibuat oleh Taylor Otwell berdasarkan framework Symfony. Ini dirancang untuk membangun aplikasi online yang mengikuti paradigma arsitektur model-view-controller (MVC).

Kerangka kerja PHP sering disukai oleh pengembang baru; PHP didokumentasikan dengan baik dan memiliki komunitas sumber daya yang aktif. Laravel adalah framework PHP yang paling populer dan seringkali menjadi framework pilihan baik untuk developer baru maupun berpengalaman. Ini digunakan untuk membangun aplikasi bisnis standar serta aplikasi tingkat perusahaan.

Menurut situs web perusahaan, perusahaan besar berikut menggunakan Laravel: Disney, Warner Brothers, Twitch, The New York Times, Pfizer, dan BBC, antara lain.

Kenapa harus menggunakan Laravel ?

Berdasarkan bintang GitHub, Laravel dilaporkan sebagai kerangka kerja backend paling populer pada tahun 2021. Berikut adalah beberapa alasan mengapa pengembang suka membangun dengan Laravel:

  • Dukungan MVC: Laravel mendukung upaya pengembangan menggunakan paradigma arsitektur MVC, membuatnya mudah digunakan dan ideal untuk aplikasi kecil dan besar. MVC merampingkan struktur pengkodean, membuatnya lebih mudah untuk dipelihara.
  • ORM yang kuat: ORM Laravel, Eloquent, membuat bekerja dengan database menjadi mudah. Eloquent menyederhanakan proses pembuatan hubungan antara objek database yang saling berhubungan
  • Mesin templating bawaan: Mesin templating bawaan Laravel (Blade) menggabungkan satu atau lebih templat dengan model data untuk menghasilkan tampilan, mengonversi templat menjadi kode PHP yang di-cache untuk meningkatkan efisiensi. Blade juga memiliki seperangkat struktur kontrol, seperti conditional dan loop, yang diterjemahkan secara internal ke rekan PHP mereka.
  • CLI yang kuat: CLI Laravel, Artisan, digunakan untuk menerbitkan aset paket, mengelola migrasi basis data, dan membuat serta menghasilkan kode boilerplate untuk pengontrol, model, dan migrasi baru. Kemampuan Artisan dapat diperluas melalui penambahan perintah khusus.
  • Beberapa sistem file: Laravel menyertakan dukungan untuk sistem penyimpanan cloud seperti Amazon S3 dan Rackspace Cloud Storage, serta penyimpanan lokal. API untuk setiap sistem sama, membuatnya mudah untuk beralih di antara alternatif penyimpanan yang berbeda. Dalam lingkungan terdistribusi, ketiga metode ini dapat digabungkan menjadi satu aplikasi untuk melayani file dari banyak lokasi.
  • Sistem autentikasi bawaan: Laravel menyediakan perancangan untuk autentikasi berbasis sesi yang aman dan juga menyediakan autentikasi melalui Sanctum untuk API dan aplikasi seluler.
  • Dokumentasi yang sangat baik: Dokumentasi resmi Laravel sangat luas namun ringkas, membuatnya berguna baik untuk pemula maupun para ahli.
  • Pengujian ekstensif: Laravel menyediakan dukungan pengujian bawaan dengan PHPUnit. Laravel juga menyediakan API pengujian yang menarik, database seeding, dan pengujian browser yang mudah.
  • Pilihan Monolith atau API: Laravel dapat digunakan dengan Livewire, untuk membuat aplikasi full-stack yang kuat di PHP. Demikian pula, Laravel dapat digabungkan dengan Inertia untuk membuat frontend berbasis JavaScript monolitik. Atau, Laravel dapat digunakan sebagai API backend yang kuat untuk aplikasi berdisi sendiri, proyek Next.js, atau frontend lain yang Anda pilih.
  • Komunitas yang besar dan terlibat: Laravel menawarkan komunitas pengembang yang luas yang bersemangat tentang kerangka kerja dan mengakomodasi pengembang dari semua tingkat keahlian
  • Skalabilitas: Ekosistem Laravel menawarkan banyak alat dan sumber daya (misalnya, Forge, Octane, Vapor) untuk mencapai skalabilitas tingkat perusahaan tanpa kerumitan terkait
  • Kode yang indah: Laravel sangat menekankan pada estetika; setiap fitur dipelajari dengan cermat dengan tujuan memberikan pengalaman pengguna yang luar biasa. Sintaksnya yang sederhana dan elegan menempatkan fungsionalitas yang ditingkatkan.

Laravel JWT authentication vs. Sanctum or Passport

Memilih jenis autentikasi untuk digunakan dalam aplikasi Laravel Anda didasarkan pada jenis aplikasi yang Anda buat. Sanctum menawarkan autentikasi berbasis sesi dan berbasis token dan bagus untuk autentikasi aplikasi satu halaman (SPA). Paspor menggunakan autentikasi JWT sebagai standar tetapi juga mengimplementasikan otorisasi OAuth 2.0 penuh.

OAuth mengizinkan otorisasi dari aplikasi pihak ketiga seperti Google, GitHub, dan Facebook, tetapi tidak semua aplikasi memerlukan fitur ini. Jika Anda ingin mengimplementasikan autentikasi berbasis token yang mengikuti standar JWT, tetapi tanpa tambahan OAuth, maka autentikasi JWT Laravel adalah pilihan terbaik Anda.

Install Laravel 9

Mari kita buat project dengan menggunakan laravel 9

composer create-project laravel/laravel demo-jwt
cd demo-jwt

Buat Database

Buat contoh database untuk Demo contoh database nya misalkan demo-jwt.

Koneksikan ke Database.

Untuk mengizinkan aplikasi Laravel kita berinteraksi dengan database yang baru dibentuk, kita harus membuat koneksi terlebih dahulu. Untuk melakukannya, kita perlu menambahkan kredensial database kita ke file .env:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=demo-jwt
DB_USERNAME=root
DB_PASSWORD=

Jalankan Artisan Migrate

Migrasi tabel Pengguna sudah diinstal sebelumnya di Laravel, jadi yang harus kita lakukan adalah menjalankannya untuk membuat tabel di database kita. Untuk membuat tabel Pengguna, gunakan perintah berikut:

php artisan migrate

Pasang Plugin JWT dan Setup JWT

Sekarang database kita sudah siap, kita akan menginstal dan menyiapkan paket autentikasi Laravel JWT. Kami akan menggunakan php-open-source-saver/jwt-auth fork dari tymondesign/jwt-auth, karena tymondesign/jwt-auth tampaknya telah ditinggalkan dan tidak kompatibel dengan Laravel 9.

Instal versi terbaru dari paket menggunakan perintah ini:

composer require php-open-source-saver/jwt-auth

Selanjutnya, kita perlu membuat konfigurasi paket menjadi publik. Salin file konfigurasi JWT dari vendor ke confi/jwt.php dengan perintah ini:

php artisan vendor:publish --provider="PHPOpenSourceSaver\JWTAuth\Providers\LaravelServiceProvider"

Sekarang, kita perlu membuat kunci rahasia untuk menangani enkripsi token. Untuk melakukannya, jalankan perintah ini:

php artisan jwt:secret

Ini akan memperbarui file .env kami dengan sesuatu seperti ini:

JWT_SECRET=xxxxxxxx

Ini adalah kunci yang akan digunakan untuk menandatangani token kami.

Konfigurasi AuthGuard

Di dalam file config/auth.php, kita perlu membuat beberapa perubahan untuk mengonfigurasi Laravel agar menggunakan JWT AuthGuard untuk mendukung autentikasi aplikasi.

Pertama, kami akan membuat perubahan berikut pada file:

    'defaults' => [
        'guard' => 'api',
        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
        ],
    ],

Dalam kode ini, kami memberi tahu penjaga API untuk menggunakan driver JWT dan menjadikan penjaga API sebagai default.

Sekarang, kita dapat menggunakan mekanisme autentikasi bawaan Laravel, dengan jwt-auth menangani pekerjaan berat!

Modify User Model

namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use PHPOpenSourceSaver\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

     /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }

}

Itu saja untuk pengaturan model user !

Buat AUTH Controller

Sekarang, kita akan buat controller untuk menangani logika inti dari proses autentikasi.

Pertama, kami akan menjalankan perintah ini untuk menghasilkan controller:

php artisan make:controller AuthController

Kemudian, kita akan mengganti konten controller dengan kode berikut:

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use App\Models\User;

class AuthController extends Controller
{

    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login','register']]);
    }

    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|string|email',
            'password' => 'required|string',
        ]);
        $credentials = $request->only('email', 'password');

        $token = Auth::attempt($credentials);
        if (!$token) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized',
            ], 401);
        }

        $user = Auth::user();
        return response()->json([
                'status' => 'success',
                'user' => $user,
                'authorisation' => [
                    'token' => $token,
                    'type' => 'bearer',
                ]
            ]);

    }

    public function register(Request $request){
        $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6',
        ]);

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => Hash::make($request->password),
        ]);

        $token = Auth::login($user);
        return response()->json([
            'status' => 'success',
            'message' => 'User created successfully',
            'user' => $user,
            'authorisation' => [
                'token' => $token,
                'type' => 'bearer',
            ]
        ]);
    }

    public function logout()
    {
        Auth::logout();
        return response()->json([
            'status' => 'success',
            'message' => 'Successfully logged out',
        ]);
    }

    public function refresh()
    {
        return response()->json([
            'status' => 'success',
            'user' => Auth::user(),
            'authorisation' => [
                'token' => Auth::refresh(),
                'type' => 'bearer',
            ]
        ]);
    }

}

Berikut penjelasan singkat tentang fungsi yang ada di AuthController:

  • constructor: kita menetapkan fungsi ini di kelas controller sehingga kita dapat menggunakan middleware auth:api di dalamnya untuk memblokir akses yang tidak diautentikasi ke controller.
  • login: Metode ini mengotentikasi pengguna dengan email dan kata sandi. Ketika pengguna berhasil diautentikasi, maka akan dapat balikan token
  • register: Metode ini mencatat pedaftaran user baru
  • logout: Metod ini mencatat user yang mengakhiri sessi.
  • refresh: Metod ini berfungsi untuk jika tokennya expire maka bisa di tukarkan lagi dengan token yang di generate baru.

Arahkan ke file routes/api.php, dan ganti isinya dengan kode berikut:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\TodoController;

Route::controller(AuthController::class)->group(function () {
    Route::post('login', 'login');
    Route::post('register', 'register');
    Route::post('logout', 'logout');
    Route::post('refresh', 'refresh');

});

Test API

Untuk test API kita bisa menggunakan Tool's seperti POST Man dan Tool's lainnya.

Klik disini untuk melihat pembahasan versi video

Demikian artikelnya, semoga bermanfaat.

 

Related Articles

Comments