Saya mulai merencanakan API REST dengan node.js, express dan mongodb. API menyediakan data untuk situs web (area publik dan pribadi) dan mungkin nanti aplikasi seluler. Frontend akan dikembangkan dengan AngularJS.
Selama beberapa hari saya membaca banyak tentang mengamankan API REST, tetapi saya tidak mendapatkan solusi final. Sejauh yang saya mengerti adalah menggunakan HTTPS untuk memberikan keamanan dasar. Tapi bagaimana saya bisa melindungi API dalam kasus penggunaan itu:
Hanya pengunjung / pengguna situs web / aplikasi yang diizinkan untuk mendapatkan data untuk area publik situs web / aplikasi tersebut
Hanya pengguna yang diautentikasi dan diotorisasi yang diizinkan untuk mendapatkan data untuk area pribadi (dan hanya data, di mana pengguna diberikan izin)
Saat ini saya berpikir untuk hanya mengizinkan pengguna dengan sesi aktif untuk menggunakan API. Untuk mengotorisasi pengguna, saya akan menggunakan paspor dan untuk izin saya perlu menerapkan sesuatu untuk diri saya sendiri. Semua ada di atas HTTPS.
Adakah yang bisa memberikan praktik atau pengalaman terbaik? Apakah ada kekurangan dalam "arsitektur" saya?
sumber
Jawaban:
Saya memiliki masalah yang sama dengan yang Anda gambarkan. Situs web yang saya bangun dapat diakses dari ponsel dan dari browser sehingga saya membutuhkan api untuk memungkinkan pengguna mendaftar, masuk, dan melakukan beberapa tugas tertentu. Selanjutnya, saya perlu mendukung skalabilitas, kode yang sama berjalan pada proses / mesin yang berbeda.
Karena pengguna dapat MENCIPTAKAN sumber daya (alias tindakan POST / PUT), Anda perlu mengamankan api Anda. Anda dapat menggunakan oauth atau Anda dapat membangun solusi Anda sendiri tetapi perlu diingat bahwa semua solusi dapat dipecahkan jika kata sandi itu benar-benar mudah ditemukan. Ide dasarnya adalah untuk mengotentikasi pengguna menggunakan nama pengguna, kata sandi, dan token, alias apitoken. Apitoken ini dapat dibuat menggunakan node-uuid dan kata sandi dapat di-hash menggunakan pbkdf2
Kemudian, Anda perlu menyimpan sesi di suatu tempat. Jika Anda menyimpannya dalam memori di objek biasa, jika Anda membunuh server dan reboot lagi sesi akan dihancurkan. Juga, ini tidak dapat diskalakan. Jika Anda menggunakan haproxy untuk memuat keseimbangan antar mesin atau jika Anda hanya menggunakan pekerja, status sesi ini akan disimpan dalam satu proses sehingga jika pengguna yang sama dialihkan ke proses / mesin lain, ia perlu melakukan otentikasi lagi. Karena itu Anda perlu menyimpan sesi di tempat umum. Ini biasanya dilakukan dengan menggunakan redis.
Ketika pengguna diautentikasi (nama pengguna + kata sandi + apitoken) buat token lain untuk sesi ini, alias accesstoken. Sekali lagi, dengan node-uuid. Kirim kepada pengguna accesstoken dan userid. Userid (kunci) dan accesstoken (nilai) disimpan dalam redis dengan dan berakhir waktu, misalnya 1 jam.
Sekarang, setiap kali pengguna melakukan operasi menggunakan api sisanya, ia harus mengirim userid dan accesstoken.
Jika Anda mengizinkan pengguna untuk mendaftar menggunakan api sisanya, Anda harus membuat akun admin dengan admin apitoken dan menyimpannya di aplikasi seluler (mengenkripsi nama pengguna + kata sandi + apitoken) karena pengguna baru tidak akan memiliki apitoken ketika mereka mendaftar.
Web juga menggunakan api ini tetapi Anda tidak perlu menggunakan apitokens. Anda dapat menggunakan express dengan toko redis atau menggunakan teknik yang sama seperti dijelaskan di atas, tetapi melewati pemeriksaan apitoken dan kembali ke pengguna, userid + accesstoken dalam cookie.
Jika Anda memiliki area pribadi, bandingkan nama pengguna dengan pengguna yang diizinkan saat mereka mengautentikasi. Anda juga dapat menerapkan peran kepada pengguna.
Ringkasan:
Alternatif tanpa apitoken adalah dengan menggunakan HTTPS dan untuk mengirim nama pengguna dan kata sandi di header Otorisasi dan cache nama pengguna di redis.
sumber
apitoken
? apakah ini kata sandi "sekunder"?Saya ingin berkontribusi kode ini sebagai solusi struktural untuk pertanyaan yang diajukan, sesuai (saya harap begitu) dengan jawaban yang diterima. (Anda dapat dengan mudah menyesuaikannya).
Server ini dapat diuji dengan curl:
sumber
Saya baru saja menyelesaikan aplikasi sampel yang melakukan ini dengan cara yang cukup mendasar, tetapi jelas. Ini menggunakan luwak dengan mongodb untuk menyimpan pengguna dan paspor untuk manajemen auth.
https://github.com/Khelldar/Angular-Express-Train-Seed
sumber
Ada banyak pertanyaan tentang pola autentikasi ISTIRAHAT di sini di SO. Ini adalah yang paling relevan untuk pertanyaan Anda:
Pada dasarnya Anda perlu memilih antara menggunakan kunci API (setidaknya aman karena kunci dapat ditemukan oleh pengguna yang tidak sah), kunci aplikasi dan kombo token (sedang), atau implementasi OAuth penuh (paling aman).
sumber
Jika Anda ingin mengamankan aplikasi Anda, maka Anda harus memulai dengan menggunakan HTTPS alih-alih HTTP , ini memastikan terciptanya saluran aman antara Anda & pengguna yang akan mencegah mengendusnya data yang dikirim kembali & keluar kepada pengguna & akan membantu menjaga data bertukar rahasia.
Anda dapat menggunakan JWT (JSON Web Tokens) untuk mengamankan API RESTful , ini memiliki banyak manfaat jika dibandingkan dengan sesi sisi server, manfaatnya terutama:
1- Lebih scalable, karena server API Anda tidak perlu mengelola sesi untuk setiap pengguna (yang bisa menjadi beban besar ketika Anda memiliki banyak sesi)
2 - JWT mandiri & memiliki klaim yang menentukan peran pengguna misalnya & apa yang dapat dia akses & dikeluarkan pada tanggal & tanggal kedaluwarsa (setelah itu JWT tidak akan valid)
3 - Lebih mudah untuk menangani lintas-penyeimbang & jika Anda memiliki beberapa server API karena Anda tidak perlu berbagi data sesi atau mengkonfigurasi server untuk merutekan sesi ke server yang sama, setiap kali permintaan dengan JWT mengenai server mana pun, itu dapat diautentikasi & resmi
4- Lebih sedikit tekanan pada DB Anda dan Anda tidak perlu terus-menerus menyimpan & mengambil id sesi & data untuk setiap permintaan
5- JWT tidak dapat dirusak jika Anda menggunakan kunci yang kuat untuk menandatangani JWT, sehingga Anda dapat mempercayai klaim dalam JWT yang dikirim dengan permintaan tanpa harus memeriksa sesi pengguna & apakah dia berwenang atau tidak , Anda cukup memeriksa JWT & kemudian Anda siap untuk mengetahui siapa & apa yang dapat dilakukan pengguna ini.
Banyak perpustakaan menyediakan cara mudah untuk membuat & memvalidasi JWT di sebagian besar bahasa pemrograman, misalnya: di node.js salah satu yang paling populer adalah jsonwebtoken
Karena REST API umumnya bertujuan untuk menjaga agar server tidak memiliki status kewarganegaraan, maka JWT lebih kompatibel dengan konsep itu karena setiap permintaan dikirim dengan token Otorisasi yang lengkap (JWT) tanpa server harus melacak sesi pengguna dibandingkan dengan sesi yang membuat server stateful sehingga ia mengingat pengguna & perannya, namun, sesi juga banyak digunakan & memiliki pro mereka, yang dapat Anda cari jika Anda mau.
Satu hal penting yang perlu diperhatikan adalah bahwa Anda harus mengirim JWT dengan aman ke klien menggunakan HTTPS & menyimpannya di tempat yang aman (misalnya di penyimpanan lokal).
Anda dapat mempelajari lebih lanjut tentang JWT dari tautan ini
sumber
Jika Anda ingin memiliki area aplikasi web yang benar-benar dikunci yang hanya dapat diakses oleh administrator dari perusahaan Anda, maka otorisasi SSL mungkin untuk Anda. Ini akan memastikan bahwa tidak ada yang dapat membuat koneksi ke server contoh kecuali mereka memiliki sertifikat resmi yang terpasang di browser mereka. Minggu lalu saya menulis artikel tentang cara mengatur server: Artikel
Ini adalah salah satu pengaturan paling aman yang akan Anda temukan karena tidak ada nama pengguna / kata sandi yang terlibat sehingga tidak ada yang bisa mendapatkan akses kecuali salah satu pengguna Anda menyerahkan file kunci ke peretas potensial.
sumber