JWT for RESTful Web Service

Melanjutkan artikel sebelumnya yaitu A Simple RESTful Web Service ,saya akan membuat sebuah token untuk aplikasi yang menerapkan web service. Token adalah suatu cara untuk menerapkan keamanan dalam web service yang berisi kode rahasia dan algoritma tertentu. Seringkali token digunakan untuk aplikasi mobile dimana user diwajibkan untuk melakukan authentication agar dapat mengakses fitur tertentu. Token tersebut akan disimpan didalam session device sehingga jika aplikasi masih menyimpan token, maka user masih dapat mengakses fitur tertentu tanpa melakukan login lagi. Sampai sini sudah ada bayangan kan gimana tujuan dari didapatkannya token? :D

https://devdojo.com/episode/laravel-and-jwt

Pada aplikasi simple restful sebelumnya belum diterapkan keamanan token jadi kita bisa mengakses data di URI /users atau dapat melakukan CRUD tanpa melalui login. Ada beberapa metode membuat token diantaranya JWT (JSON Web Token) ,OAuth, Passport dll. Namun kali ini saya menggunakan JWT Authentication yaitu dengan melakukan verifikasi user melalui digital signature saat login.

Proses JWT Authentication :
1.User login dengan menginputkan credentials (username, email, password dll) lalu mengirim request post ke server. 
2. Server menerima request lalu merespon dengan mengembalikan sebuah token.
3. JWT disimpan didalam local storage browser atau mekanisme storage lainnya.
4. Jika user mengirim request yang lain, maka perlu meng-include-kan token yang didapat tadi kedalam request header tersebut.
5. Server mengecek token tersebut apakan valid atau tidak lalu mengembalikan sebuah response.
6. Aplikasi akan menggunakan token tersebut sampai user melakukan logout aplikasi secara manual atau token di destroy. Selama token tersebut valid, maka user masih dapat mengakses resources tertentu.
7. Jika token destroy atau dimanipulasi, maka user akan di redirect ke tahap login user dengan menginputkan credentials.
8. Jika credentials valid, maka server akan mengirimkan token baru.


Implementasi JWT Authentication pada project Laravel
Kita dapat menginstall package dari Tymon di github untuk mengimplementasikan JWT Authentication didalam Laravel. Berikut langkah-langkahnya :

  1. Install dan configurasi
    buka file composer.json lalu tambahkan require :
"require": {
"tymon/jwt-auth": "0.5.*"
}

Pastikan path di terminal berada di lokasi project laravel berada. Lalu ketikkan perintah composer update di terminal. Setelah berhasil tambahkan providers dan aliases didalam array di file app.php :

  • providers :
'Tymon\JWTAuth\Providers\JWTAuthServiceProvider'
  • aliases :
'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth',
'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory'

Kemudian publish configurasi tersebut didalam terminal :

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

Dan yang terakhir set sebuah kunci rahasia didalam token. Lakukan command di terminal :

php artisan jwt:generate

2. Membuat Fungsi Login dan Membuat Token

Setelah selesai berhasil melakukan configurasi JWT di dalam project Laravel, kemudian waktunya membuat fungsi login didalam Controller. Untuk membedakan controller API dengan controller web, buat folder API didalam folder controllers yang akan digunakan sebagai tempat controller API.

Controller APIUserController.php kita pindahkan kedalam folder API. Lalu kita bikin controller baru bernama AuthController.php yang berfungsi sebagai controller authentication JWT. Buka terminal dan lakukan command :

php artisan make:controller API\APIAuthController

Maka akan muncul file APIAuthController.php didalam folder App\Http\Controllers\API.

Kita menggunakan try-catch sebagai handle process. Didalam closure try {} digunakan untuk memproses credentials yang digunakan untuk login dengan paramter email dan password. Jika credentials valid, maka token dibuat oleh JWTAuth::attempt based on credentials.

Jika credentials tidak valid, maka dikembalikan response array dengan key sukses bernilai false, pesan yang dikirim dan yang terpenting adalah status code. Status code 404 menandakan bahwa service tidak menemukan request yang diminta.

Nah untuk closure catch(\Exception ..) digunakan jika terjadi kesalahan didalam proses try{}, maka dikembalikan response suses false dengan pesan dan status code yang sesuai.

Jika proses didalam try{} berhasil, maka dikembalikan responses status true dengan pesan berhasil dan status code 200. Response key dan value yang dikirim digunakan sebagai parameter aplikasi lain dalam memvalidasi proses web service. Contohnya didalam mobile app, jika status true maka mobile app wajib mendapatkan response status code bernilai 200 yang artinya proses service didalam mobile app berhasil. Sebaliknya jika gagal dalam mendapatkan service, hindari code status bernilai 500 yang artinya internal server error. Jika aplikasi mendapatkan status code 500, contohnya dalam mobile app, maka akan terjadi force close .Hal ini menjadi issue penting dalam membangun web service.

3. Test Endpoint di Postman

Buat endpoint didalam file routes/api.php lalu tambahkan endpoint login :

$api->version('v1',['namespace'=>'App\Http\Controllers'], function($api){
     $api->post('login','API\AuthController@login');
});

Lalu test api login tersebut di postman. Jangan lupa untuk menambahkan Content-Type : application/json didalam Headers Postman. Didalam Body tambahkan paramater dengan value yang sudah ada di database users.

Dan berhasil deh kita mendapatkan token.

4. Menambahkan middleware JWT Auth

Setelah berhasil mendapatkan token, saatnya membuat route middleware yaitu API apa saja yang bisa diakses setelah user melakukan login dan aplikasi telah mendapatkan token. Untuk project laravel kali ini, kita akan membuat middleware pada API dengan prefix \users.

Daftarkan middleware jwt didalam list Route Middleware .Buka App\Http\Middleware\Kernel.php lalu tambahkan jwt.auth dan jwt.refresh seperti pada dokumentasi github .

Setelah berhasil mendaftarkan jwt didalam list route middleware, saatnya kita tambahkan kedalam route group /users .Buka api.php didalam folder routes lalu tambahkan middeware jwt.auth di dalam array group routes :

Test di postman dan cobalah untuk mengakses api /users apakah bisa diakses? Akan terjadi message error : token not provided karena pada postman tidak menyertakan headers authentication dalam mengirim request. Sekarang kita tambahkan headers Authentication dengan value Bearer [token] :

Token berasal dari token yang dikirim pada api login lalu kita tambahkan setelah kunci Bearer. Disini kita telah berhasil melakukan middleware didalam route group. Yey!

5. Membuat fungsi Logout

Kita telah berhasil membuat fungsi login guna mendapatkan token lalu menambahkan middleware jwt auth kedalam route group, langkah selanjutnya yaitu membuat fungsi logout yang tujuannya untuk menghapus token yang telah disimpan didalam aplikasi agar tokentidak dapat digunakan kembali.

Buka AuthController lalu tambahkan fungsi logout :

Kemudian tambahkan endpoint logout didalam route api.php .Ingat, api logout digunakan ketika kondisi user sudah melakukan login dan telah mengakses api yang telah diberikan middleware jwt.auth . Artinya adalah aplikasi masih dalam menyimpan token. Jadi kita tambahkan endpoint logout didalam route group /users :

Saatnya kita lakukan test di postman. Tambahkan headers Authentication dengan value berupa token yang telah disimpan sebelumnya :

Jangan lupa didalam Body isi parameter token dengan value berupa token (tanpa Bearer). Dan service berhasil mengirim respon berhasil logout.

Coba deh akses api yang telah diberi middleware jwt.auth dengan token yang sudah ada, apakah masih bisa diakses? jawabannya tidak, karena token telah invalid.

So far, kita sudah membuat service default yang wajib ada di dalam web service pada umumnya. Yey!