Memahami JWT: Dasar-Dasar, Keamanan, dan Kasus Penggunaan
Dalam lanskap pengembangan web modern, otentikasi dan otorisasi pengguna memainkan peran penting dalam mengamankan aplikasi dan data sensitif. JSON Web Token (JWT) telah muncul sebagai standar industri yang populer untuk mewakili klaim secara aman antar dua pihak. Posting blog ini bertujuan untuk menyediakan panduan komprehensif untuk JWT, mencakup dasar-dasarnya, aspek keamanan, kasus penggunaan, dan praktik terbaik.
Daftar Isi
- Pendahuluan tentang JWT
- Apa itu JWT?
- Mengapa Menggunakan JWT?
- Struktur JWT
- Anatomi JWT
- Header
- Payload
- Signature
- Cara Kerja JWT: Alur Otentikasi
- Otentikasi Pengguna
- Penerbitan JWT
- Akses Sumber Daya Terlindungi
- Validasi JWT
- Keamanan JWT
- Algoritma Enkripsi
- Pencegahan Serangan Cross-Site Scripting (XSS)
- Pencegahan Serangan Cross-Site Request Forgery (CSRF)
- Menangani Penyimpanan Token
- Masa Berlaku Token dan Refresh Token
- Kasus Penggunaan JWT
- Otentikasi
- Otorisasi
- Pertukaran Informasi
- Single Sign-On (SSO)
- Praktik Terbaik JWT
- Memilih Algoritma yang Kuat
- Jaga Kerahasiaan Kunci Rahasia Anda
- Simpan Token dengan Aman
- Gunakan HTTPS
- Validasi dan Bersihkan Data Input
- Terapkan Batasan Masa Berlaku Token
- JWT vs Sesi
- Keunggulan JWT
- Kekurangan JWT
- Kapan Menggunakan JWT vs Sesi
- Library dan Implementasi JWT
- JavaScript (Node.js, Browser)
- Python
- Java
- PHP
- Ruby
- Debugging dan Pemecahan Masalah JWT
- Memecahkan Kode JWT
- Kesalahan Umum dan Solusi
- Kesimpulan
1. Pendahuluan tentang JWT
Apa itu JWT?
JSON Web Token (JWT) adalah standar industri terbuka (RFC 7519) yang ringkas, mandiri, dan aman untuk mengirimkan informasi antara pihak-pihak sebagai objek JSON. Informasi ini dapat diverifikasi dan dipercaya karena ditandatangani secara digital menggunakan kunci rahasia (dengan algoritma HMAC) atau kunci publik/privat menggunakan RSA atau ECDSA.
JWT pada dasarnya adalah string yang dikodekan, yang terdiri dari tiga bagian yang dipisahkan oleh titik (.
):
- Header
- Payload
- Signature
Mengapa Menggunakan JWT?
JWT menawarkan beberapa keuntungan yang membuatnya menjadi pilihan populer untuk otentikasi dan otorisasi:
- Tanpa kewarganegaraan (Stateless): JWT mandiri dan tidak memerlukan server untuk menyimpan informasi sesi. Setiap token berisi semua informasi yang diperlukan untuk memvalidasi pengguna.
- Skalabel: Karena JWT tidak bergantung pada sesi server, mereka mudah diskalakan di berbagai server dan domain.
- Aman: JWT dapat ditandatangani menggunakan algoritma kriptografi, memastikan bahwa data tidak dirusak dalam perjalanan.
- Ringkas: JWT relatif kecil ukurannya, sehingga efisien untuk transmisi melalui header HTTP atau URL.
- Kompatibel lintas domain: JWT dapat digunakan untuk otentikasi di berbagai domain dan aplikasi.
Struktur JWT
JWT terdiri dari tiga bagian utama:
- Header: Menentukan algoritma enkripsi dan tipe token (JWT).
- Payload: Berisi klaim atau pernyataan tentang entitas (pengguna) dan data tambahan apa pun.
- Signature: Dihitung dengan mengenkripsi header dan payload menggunakan kunci rahasia dan algoritma yang ditentukan.
2. Anatomi JWT
Header
Header JWT adalah objek JSON yang menentukan tipe token (typ
) dan algoritma hashing yang digunakan untuk menandatangani token (alg
). Contoh:
{
"alg": "HS256",
"typ": "JWT"
}
alg
(Algorithm): Menentukan algoritma kriptografi yang digunakan untuk menandatangani token. Contoh umum termasukHS256
(HMAC SHA256),RS256
(RSA Signature with SHA256), danES256
(ECDSA Signature with SHA256).typ
(Type): Menentukan tipe token, yang biasanyaJWT
.
Header kemudian dikodekan dengan Base64Url untuk membentuk bagian pertama dari JWT.
Payload
Payload JWT berisi serangkaian klaim. Klaim adalah pernyataan tentang entitas (biasanya pengguna) dan data tambahan apa pun. Ada tiga jenis klaim:
- Registered Claims: Klaim yang telah ditentukan yang tidak wajib tetapi direkomendasikan untuk memberikan interoperabilitas. Contoh termasuk
iss
(issuer),sub
(subject),aud
(audience),exp
(expiration time),nbf
(not before),iat
(issued at time), danjti
(JWT ID). - Public Claims: Klaim yang dapat didefinisikan oleh pengguna JWT. Disarankan untuk menghindari bentrokan nama dengan mendaftarkan klaim di IANA JSON Web Token Registry atau dengan menggunakan URI yang berisi nama domain yang tahan bentrokan.
- Private Claims: Klaim khusus informasi yang disetujui antara pihak-pihak yang menggunakannya.
Contoh Payload:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}
sub
(Subject): Mengidentifikasi entitas yang menjadi subjek token.name
(Name): Menyediakan nama pengguna.admin
(Admin): Menunjukkan apakah pengguna memiliki hak administratif.iat
(Issued At): Mewakili waktu ketika token dikeluarkan (dalam detik sejak waktu Unix Epoch).
Payload kemudian dikodekan dengan Base64Url untuk membentuk bagian kedua dari JWT.
Signature
Signature JWT dihitung dengan mengambil header yang dikodekan Base64Url, payload yang dikodekan Base64Url, kunci rahasia, algoritma yang ditentukan dalam header, dan menandatanganinya. Prosesnya adalah sebagai berikut:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
Signature memastikan bahwa token tidak dirusak dalam perjalanan dan dapat diverifikasi oleh pihak yang berwenang yang memiliki kunci rahasia.
Misalnya, menggunakan algoritma HS256
dan kunci rahasia secret
:
const header = base64UrlEncode(JSON.stringify({ alg: "HS256", typ: "JWT" }));
const payload = base64UrlEncode(JSON.stringify({ sub: "1234567890", name: "John Doe", admin: true }));
const signature = HMACSHA256(header + "." + payload, "secret");
Signature kemudian dikodekan dengan Base64Url dan ditambahkan ke header dan payload yang dikodekan Base64Url yang dipisahkan oleh titik.
3. Cara Kerja JWT: Alur Otentikasi
JWT digunakan dalam alur otentikasi tipikal dengan cara berikut:
- Otentikasi Pengguna: Pengguna memasukkan kredensial mereka (mis., nama pengguna dan kata sandi) ke dalam sistem.
- Penerbitan JWT: Setelah kredensial diverifikasi, server menghasilkan JWT yang berisi informasi tentang pengguna.
- Akses Sumber Daya Terlindungi: Saat pengguna ingin mengakses sumber daya terlindungi, mereka mengirimkan JWT bersama dengan permintaannya (biasanya di header Authorization).
- Validasi JWT: Server memvalidasi JWT untuk memastikan bahwa itu valid dan tidak dirusak. Jika valid, server memberikan akses ke sumber daya yang diminta.
Otentikasi Pengguna
Alur dimulai ketika pengguna mencoba untuk masuk ke aplikasi. Pengguna memberikan kredensial mereka, seperti nama pengguna dan kata sandi, yang kemudian diverifikasi terhadap database atau sistem otentikasi lainnya.
Penerbitan JWT
Setelah kredensial pengguna berhasil diverifikasi, server menerbitkan JWT. JWT ini berisi informasi tentang pengguna, seperti ID pengguna, nama, peran, dan klaim lainnya yang relevan. Server menandatangani JWT menggunakan kunci rahasia untuk memastikan integritasnya.
Akses Sumber Daya Terlindungi
Ketika pengguna ingin mengakses sumber daya terlindungi, mereka menyertakan JWT dalam header Authorization dari permintaan HTTP mereka. Konvensinya adalah menggunakan skema “Bearer” diikuti oleh JWT:
Authorization: Bearer <token>
Validasi JWT
Ketika server menerima permintaan dengan JWT, itu memvalidasi token untuk memastikan bahwa itu asli dan belum dirusak. Proses validasi melibatkan langkah-langkah berikut:
- Dekode Token: Token diuraikan menjadi tiga bagiannya: header, payload, dan signature.
- Verifikasi Signature: Signature diverifikasi menggunakan kunci rahasia yang sama yang digunakan untuk menandatangani token. Ini memastikan bahwa token belum dimodifikasi.
- Validasi Klaim: Server memvalidasi klaim dalam payload, seperti klaim expiration (
exp
), klaim issuer (iss
), dan klaim audience (aud
), untuk memastikan bahwa token masih valid dan relevan.
Jika semua langkah validasi berhasil, server menganggap token valid dan memberikan akses ke sumber daya yang diminta.
4. Keamanan JWT
Keamanan JWT sangat penting untuk melindungi aplikasi Anda dari akses tidak sah dan pelanggaran data. Berikut adalah beberapa pertimbangan keamanan utama:
Algoritma Enkripsi
Pilihan algoritma enkripsi memengaruhi keamanan JWT secara signifikan. Berikut adalah beberapa algoritma yang umum digunakan:
- HS256 (HMAC SHA256): Algoritma simetris yang menggunakan kunci rahasia tunggal untuk menandatangani dan memverifikasi token. Mudah diimplementasikan tetapi kurang aman daripada algoritma asimetris.
- RS256 (RSA Signature with SHA256): Algoritma asimetris yang menggunakan pasangan kunci publik/privat. Kunci privat digunakan untuk menandatangani token, dan kunci publik digunakan untuk memverifikasi token. Lebih aman daripada HS256 tetapi membutuhkan lebih banyak sumber daya komputasi.
- ES256 (ECDSA Signature with SHA256): Algoritma asimetris yang menggunakan Kurva Elliptic Digital Signature Algorithm (ECDSA). Menawarkan keamanan yang kuat dengan ukuran kunci yang lebih kecil daripada RSA.
Praktik Terbaik: Gunakan algoritma asimetris seperti RS256 atau ES256 untuk keamanan yang lebih baik. Hindari menggunakan HS256 dalam produksi karena kunci rahasia harus tetap rahasia dan tidak boleh dibagikan antara pihak.
Pencegahan Serangan Cross-Site Scripting (XSS)
Serangan XSS terjadi ketika penyerang menyuntikkan skrip berbahaya ke dalam aplikasi web yang dilihat oleh pengguna lain. Untuk mencegah serangan XSS yang melibatkan JWT:
- Hindari Menyimpan JWT di Penyimpanan Lokal: Penyimpanan Lokal rentan terhadap serangan XSS karena skrip apa pun di halaman web dapat mengaksesnya.
- Gunakan Cookie HTTP-only: Simpan JWT di cookie HTTP-only. Cookie HTTP-only tidak dapat diakses oleh JavaScript, sehingga mengurangi risiko pencurian token melalui XSS.
- Terapkan Kebijakan Keamanan Konten (CSP): CSP memungkinkan Anda untuk mengontrol sumber daya yang dapat dimuat oleh browser, mengurangi risiko serangan XSS.
Pencegahan Serangan Cross-Site Request Forgery (CSRF)
Serangan CSRF terjadi ketika penyerang menipu pengguna untuk melakukan tindakan yang tidak diinginkan atas nama mereka. Untuk mencegah serangan CSRF yang melibatkan JWT:
- Gunakan Token Anti-CSRF: Sertakan token anti-CSRF dalam permintaan, yang diverifikasi oleh server untuk memastikan bahwa permintaan berasal dari sumber yang sah.
- Gunakan Metode Permintaan yang Benar: Gunakan metode permintaan HTTP yang tepat (mis., gunakan POST untuk mengubah data dan GET untuk mengambil data).
- Terapkan Perlindungan CORS: Cross-Origin Resource Sharing (CORS) mencegah situs web jahat untuk membuat permintaan lintas-origin ke aplikasi Anda.
Menangani Penyimpanan Token
Cara Anda menyimpan JWT sangat memengaruhi keamanannya. Berikut adalah beberapa opsi penyimpanan dan pertimbangan terkait:
- Cookie HTTP-only: Opsi yang aman karena cookie HTTP-only tidak dapat diakses oleh JavaScript, mengurangi risiko serangan XSS.
- Session Storage: Mirip dengan penyimpanan lokal tetapi hanya menyimpan data selama durasi sesi browser. Lebih aman daripada penyimpanan lokal tetapi masih rentan terhadap serangan XSS.
- Penyimpanan Lokal: Harus dihindari karena rentan terhadap serangan XSS.
- Di dalam Memori (Variabel JavaScript): Paling aman jika token diperlukan hanya selama rentang hidup skrip saat ini, tetapi hilang setelah halaman dimuat ulang.
Praktik Terbaik: Gunakan cookie HTTP-only untuk penyimpanan token yang aman. Jika Anda harus menyimpan token di sisi klien, pertimbangkan untuk menggunakan penyimpanan sesi dan menerapkan langkah-langkah mitigasi XSS tambahan.
Masa Berlaku Token dan Refresh Token
Menetapkan masa berlaku yang singkat untuk JWT dan menggunakan refresh token membantu mengurangi risiko yang terkait dengan token yang dicuri atau disusupi:
- Masa Berlaku Token: Setel masa berlaku yang singkat untuk JWT (mis., 15 menit hingga 1 jam). Ini membatasi jendela waktu bahwa token yang dicuri dapat digunakan.
- Refresh Token: Gunakan refresh token untuk mengeluarkan token akses baru tanpa mengharuskan pengguna untuk masuk kembali. Refresh token memiliki masa berlaku yang lebih lama dan disimpan dengan aman di server.
Alur Refresh Token:
- Pengguna mengotentikasi dan menerima token akses dan token refresh.
- Token akses digunakan untuk mengakses sumber daya terlindungi hingga kedaluwarsa.
- Ketika token akses kedaluwarsa, aplikasi menggunakan token refresh untuk meminta token akses baru.
- Server memvalidasi token refresh dan menerbitkan token akses baru.
- Token refresh juga dapat diputar untuk meningkatkan keamanan.
5. Kasus Penggunaan JWT
JWT dapat digunakan dalam berbagai kasus penggunaan, termasuk:
Otentikasi
Kasus penggunaan JWT yang paling umum adalah untuk otentikasi. Ketika pengguna masuk, server menghasilkan JWT dan mengembalikannya ke klien. Klien kemudian menyimpan JWT dan menyertakannya dalam header Authorization dari setiap permintaan ke sumber daya terlindungi. Server memvalidasi JWT untuk mengotentikasi pengguna.
Otorisasi
JWT juga dapat digunakan untuk otorisasi. Payload JWT dapat berisi informasi tentang peran dan izin pengguna. Server dapat menggunakan informasi ini untuk menentukan apakah pengguna memiliki izin untuk mengakses sumber daya tertentu.
Pertukaran Informasi
JWT dapat digunakan untuk bertukar informasi antara pihak-pihak. Karena JWT ditandatangani, penerima dapat memverifikasi integritas dan keaslian informasi. JWT sering digunakan untuk meneruskan informasi pengguna antara layanan yang berbeda dalam arsitektur microservice.
Single Sign-On (SSO)
JWT dapat digunakan untuk mengimplementasikan Single Sign-On (SSO). SSO memungkinkan pengguna untuk masuk sekali dan mengakses beberapa aplikasi tanpa harus masuk kembali. Ketika pengguna masuk ke salah satu aplikasi, server menerbitkan JWT yang dapat digunakan untuk mengotentikasi pengguna ke aplikasi lain.
6. Praktik Terbaik JWT
Untuk memastikan keamanan dan efektivitas JWT, ikuti praktik terbaik ini:
Memilih Algoritma yang Kuat
Pilih algoritma yang kuat yang sesuai untuk kebutuhan keamanan Anda. Algoritma asimetris seperti RS256 atau ES256 lebih aman daripada algoritma simetris seperti HS256.
Jaga Kerahasiaan Kunci Rahasia Anda
Kunci rahasia yang digunakan untuk menandatangani JWT harus disimpan dengan aman dan tidak boleh dibagikan dengan pihak yang tidak berwenang. Gunakan variabel lingkungan atau brankas rahasia untuk menyimpan kunci rahasia Anda.
Simpan Token dengan Aman
Simpan JWT dengan aman di sisi klien. Gunakan cookie HTTP-only untuk mencegah serangan XSS. Hindari menyimpan JWT di penyimpanan lokal.
Gunakan HTTPS
Selalu gunakan HTTPS untuk semua komunikasi antara klien dan server. HTTPS mengenkripsi data dalam perjalanan, mencegah penyadap mencuri JWT.
Validasi dan Bersihkan Data Input
Validasi dan bersihkan semua data input untuk mencegah serangan injeksi. Ini termasuk memvalidasi klaim dalam payload JWT dan membersihkan data input dari pengguna.
Terapkan Batasan Masa Berlaku Token
Terapkan batasan masa berlaku token untuk membatasi masa pakai JWT. Gunakan refresh token untuk mengeluarkan token akses baru tanpa mengharuskan pengguna untuk masuk kembali.
7. JWT vs Sesi
JWT dan sesi adalah dua mekanisme otentikasi yang berbeda. Sesi melibatkan penyimpanan informasi pengguna di server, sedangkan JWT mandiri dan berisi semua informasi yang diperlukan di dalam token itu sendiri.
Keunggulan JWT
- Stateless: JWT stateless, yang berarti bahwa server tidak perlu menyimpan informasi sesi. Ini membuat JWT lebih mudah diskalakan dan didistribusikan.
- Kompatibel lintas domain: JWT dapat digunakan untuk otentikasi di berbagai domain dan aplikasi.
- Skalabel: Karena JWT tidak bergantung pada sesi server, mereka mudah diskalakan di berbagai server dan domain.
Kekurangan JWT
- Ukuran: JWT lebih besar daripada ID sesi, yang dapat berdampak pada kinerja.
- Pencabutan: Mencabut JWT membutuhkan upaya tambahan, seperti menjaga daftar hitam.
- Kompleksitas: JWT mungkin lebih kompleks untuk diimplementasikan dan dikelola daripada sesi.
Kapan Menggunakan JWT vs Sesi
- Gunakan JWT:
- Saat Anda membutuhkan solusi stateless.
- Saat Anda perlu mengotentikasi pengguna di berbagai domain dan aplikasi.
- Saat Anda membangun aplikasi microservice.
- Gunakan Sesi:
- Saat Anda membutuhkan cara sederhana dan langsung untuk mengelola otentikasi pengguna.
- Saat Anda perlu menyimpan sejumlah besar data sesi.
- Saat Anda membutuhkan kemampuan untuk mencabut sesi pengguna secara instan.
8. Library dan Implementasi JWT
Banyak library dan implementasi JWT tersedia dalam berbagai bahasa pemrograman. Berikut adalah beberapa contoh:
JavaScript (Node.js, Browser)
- jsonwebtoken (Node.js): Library yang populer dan banyak digunakan untuk membuat dan memverifikasi JWT di Node.js.
- jsrsasign (Browser): Library JavaScript yang menyediakan dukungan untuk berbagai algoritma kriptografi, termasuk yang digunakan dalam JWT.
Python
- PyJWT: Library Python sederhana dan mudah digunakan untuk membuat dan memverifikasi JWT.
Java
- java-jwt: Library Java yang menyediakan API yang lancar dan aman untuk bekerja dengan JWT.
PHP
- firebase/php-jwt: Library PHP sederhana untuk mengenkode dan mendekode JWT.
Ruby
- jwt (Ruby): Library Ruby yang memungkinkan Anda untuk mengenkode dan mendekode JWT.
9. Debugging dan Pemecahan Masalah JWT
Debugging dan memecahkan masalah JWT terkadang bisa jadi menantang. Berikut adalah beberapa tips dan alat untuk membantu Anda:
Memecahkan Kode JWT
Anda dapat menggunakan alat online seperti jwt.io untuk mendekode dan memeriksa konten JWT. Ini memungkinkan Anda untuk melihat header, payload, dan signature token.
Kesalahan Umum dan Solusi
- Signature Tidak Valid: Memastikan bahwa kunci rahasia yang digunakan untuk memverifikasi signature sama dengan yang digunakan untuk menandatangani token.
- Token Kedaluwarsa: Periksa klaim expiration (
exp
) di payload untuk memastikan bahwa token belum kedaluwarsa. - Masalah Klaim: Validasi klaim issuer (
iss
) dan audience (aud
) untuk memastikan bahwa token dikeluarkan oleh pihak yang sah dan ditujukan untuk penerima yang benar. - Masalah CORS: Konfigurasikan pengaturan CORS server Anda untuk mengizinkan permintaan dari domain yang tepat.
10. Kesimpulan
JSON Web Token (JWT) menyediakan mekanisme yang aman dan efisien untuk otentikasi dan otorisasi pengguna dalam aplikasi web. Dengan memahami dasar-dasar, aspek keamanan, dan kasus penggunaan JWT, Anda dapat mengimplementasikannya secara efektif dalam aplikasi Anda sendiri. Ikuti praktik terbaik dan gunakan library yang tepat untuk memastikan keamanan dan skalabilitas solusi berbasis JWT Anda. Semoga artikel ini memberikan pemahaman komprehensif tentang JWT dan memungkinkan Anda untuk menggunakannya dengan percaya diri.
“`