Saya menerapkan sistem otentikasi berbasis token untuk REST API menggunakan token akses berumur pendek dan token refresh yang berumur panjang. Ini adalah ikhtisar abstrak dari titik akhir API yang relevan (HTTPS diberlakukan untuk semua titik akhir):
Titik akhir:
POST /register/
POST /login/
POST /logout/
POST /password/change/
Penerapan:
POST /register/
:
- Permintaan: Klien mengirim nama pengguna, email, dan kata sandi di JSON.
- Tindakan server:
- Memvalidasi input, membuat pengguna dalam basis data (menyimpan id pengguna, nama pengguna, email, dan kata sandi hash).
- Membuat token akses berumur pendek dalam format JWT (berisi id pengguna, tanggal yang dikeluarkan, dan tanggal kedaluwarsa).
- Membuat token penyegaran berumur panjang sebagai string UUID dan menyimpannya dalam basis data (menyimpan id pengguna dan menyegarkan token).
- Respons: Server mengembalikan token akses dan menyegarkan token di JSON.
POST /login/
:
- Permintaan: Klien mengirim nama pengguna dan kata sandi di JSON.
- Tindakan server:
- Memvalidasi input, memeriksa apakah kredensial valid dengan memeriksa database.
- Jika kredensial valid, buat token akses berumur pendek dan refresh token berumur panjang seperti yang disebutkan sebelumnya.
- Respons: Sama seperti
/register/
, mengembalikan token akses dan menyegarkan token di JSON.
POST /logout/
:
- Permintaan: Klien mengirimkan token penyegaran di
Authorization
header sebagaiBearer
token. - Tindakan server:
- Memvalidasi token penyegaran dengan memeriksa basis data penyegaran token.
- Menghapus token penyegaran dari database.
Catatan: Ini membuat token akses valid, tetapi karena akan berumur pendek (1 jam atau lebih, saya pikir itu akan baik-baik saja).
- Respons: Mengembalikan apakah permintaan logout berhasil diproses di JSON.
POST /password/change/
:
- Permintaan: Klien mengirimkan token akses di
Authorization
header sebagaiBearer
token, dan juga mengirimkan kata sandi lama dan kata sandi baru di JSON melalui HTTPS. - Tindakan server:
- Mendekode token akses untuk mengambil pengguna, dan memeriksa kata sandi lama pengguna dengan database.
- Menyetel hash kata sandi pengguna dalam database ke hash kata sandi baru.
- Menghapus semua token penyegaran yang terkait dengan pengguna di basis data token penyegaran untuk dasarnya log out sesi yang ada (meninggalkan token akses berumur pendek).
- Respons: Mengembalikan apakah permintaan perubahan kata sandi berhasil diproses di JSON.
Pertanyaan:
- Apakah pendekatan ini aman? Secara khusus:
- Apakah mengirim nama pengguna dan kata sandi melalui JSON aman jika dilakukan melalui HTTPS? Bagaimana saya mencegah domain tidak sah melakukan panggilan ke titik akhir ini? Selanjutnya, bagaimana saya mencegah login terprogram?
- Haruskah token penyegaran di-hash sebelum menyimpannya dalam database, atau apakah saya hanya paranoid?
- Jika klien adalah browser web, bagaimana cara saya menyimpan token refresh dengan aman pada klien?
- Satu ide yang saya miliki untuk menyimpan token refresh adalah: ketika pengguna login, selain mengirim token refresh ke klien, server menyimpan token dalam
HttpOnly
cookie dengansecure
bendera. Otorisasi masih akan dilakukan melaluiAuthorization
tajuk, tetapi ketika klien pada awalnya memuat, itu dapat mengirimGET
permintaan ke titik akhir yang memeriksa apakah cookie berisi token penyegaran yang valid, dan jika demikian, kembalikan ke pengguna di JSON. Dengan kata lain, satu-satunya waktu cookie akan benar-benar digunakan adalah mengembalikan token refresh di dalam cookie kepada klien. Apakah pendekatan ini aman? Saya pikir itu akan mencegah CSRF karena tidak ada efek samping ketika meminta token penyegaran dari cookie, tetapi apakah ada cara lain penyerang bisa mencegat token penyegaran (dengan asumsi HTTPS)?
- Satu ide yang saya miliki untuk menyimpan token refresh adalah: ketika pengguna login, selain mengirim token refresh ke klien, server menyimpan token dalam