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
Jawaban:
Iya. Header, params permintaan, dan badan permintaan dienkripsi selama komunikasi.
Begitu berada di sisi server, jangan login badan permintaan :-)
Kamu tidak bisa. Pada dasarnya, begitu API ada di WWW, itu secara otomatis terkena semua jenis kedengkian. Yang terbaik yang bisa Anda lakukan adalah bersiap-siap dan waspada terhadap ancaman. Setidaknya tentang hal-hal yang menjadi perhatian Anda. Coba lihat di sini .
Pendekatan yang mungkin untuk masalah tersebut dapat menerapkan (atau membuat kontrak) seorang Manajer API .
Manajer API On-premise dapat mengurangi permukaan serangan karena semua titik akhir di belakang AM belum tentu publik.
Anda dapat mencapai hasil yang sama dengan beberapa produk di cloud, tetapi mereka bukan kepalang mahal untuk arus utama.
Bagaimanapun, titik akhir Manajemen API akan tetap terkena serangan.
Jika dengan login terprogram yang Anda maksud adalah serangan dengan kekerasan, ambang (jumlah maksimum permintaan yang diizinkan per detik) dan daftar hitam harus cukup untuk mencegah desakan penyerang. Untuk informasi lebih lanjut, lihat di sini .
Banyak Manajer API menyediakan di luar kotak Konfigurasi Batas API dan Daftar Putih .
Jika Anda terbiasa dengan Google API Console, maka Anda dapat menebak apa yang bisa dilakukan oleh Manajer API.
Apakah token penyegaran adalah UUID biasa atau apa pun, saya tidak suka mengekspos detail implementasi semacam ini. Jadi saya akan menyarankan untuk hash. Bagi saya, semakin buram detail implementasi dari lapisan keamanan, semakin baik.
Mengenai keamanan JWT, lihat di sini .
Anda mungkin tertarik dengan JSON Web Token (JWT) - Penyimpanan di sisi klien .
sumber
sessionStorage
tidak akan berfungsi. Juga,localStorage
dandocument.cookie
tampaknya tidak aman karena mereka dapat diakses oleh JavaScript. Apakah pendekatan saya masuk akal, atau berpotensi tidak aman?document.cookie
atau cookie HttpOnly dengan bendera aman, mirip dengan pendekatan yang saya sebutkan di atas?