Ada banyak pertanyaan yang diajukan di sini, dan tampaknya meskipun pertanyaan-pertanyaan itu ditanyakan dalam konteks Node dan paspor. Namun pertanyaan sebenarnya lebih banyak tentang alur kerja daripada bagaimana melakukan ini dengan teknologi tertentu.
Mari kita gunakan contoh setup @Keith, dimodifikasi sedikit untuk keamanan tambahan:
- Server web di
https://example.com
melayani aplikasi klien Javascript satu halaman
- Layanan web RESTful di
https://example.com/api
menyediakan dukungan server ke aplikasi klien kaya
- Server diimplementasikan dalam Node dan passport.js.
- Server memiliki basis data (apa pun) dengan tabel "pengguna".
- Nama pengguna / kata sandi dan Facebook Connect ditawarkan sebagai opsi otentikasi
- Klien kaya membuat permintaan REST
https://example.com/api
- Mungkin ada klien lain (aplikasi telepon, misalnya) yang menggunakan layanan web di
https://example.com/api
tetapi tidak tahu tentang server web di https://example.com
.
Perhatikan bahwa saya menggunakan HTTP aman. Ini menurut pendapat saya suatu keharusan untuk setiap layanan yang tersedia di tempat terbuka, karena informasi sensitif seperti kata sandi dan token otorisasi lewat antara klien dan server.
Otentikasi nama pengguna / kata sandi
Mari kita lihat cara kerja otentikasi lama yang sederhana terlebih dahulu.
- Pengguna terhubung ke
https://example.com
- Server menyajikan aplikasi Javascript yang kaya yang merender halaman awal. Entah di halaman itu ada formulir login.
- Banyak bagian dari aplikasi satu halaman ini belum diisi dengan data karena pengguna tidak masuk. Semua bagian ini memiliki pendengar acara pada acara "masuk". Semua ini adalah hal-hal sisi klien, server tidak mengetahui peristiwa ini.
- Pengguna memasukkan login dan kata sandi dan menekan tombol kirim, yang memicu penangan Javascript untuk merekam nama pengguna dan kata sandi dalam variabel sisi klien. Kemudian pawang ini memicu acara "masuk". Sekali lagi, ini semua tindakan sisi klien, kredensial belum dikirim ke server .
- Pendengar acara "masuk" dipanggil. Masing-masing sekarang perlu mengirim satu atau lebih permintaan ke RESTful API di
https://example.com/api
untuk mendapatkan data spesifik pengguna untuk di-render di halaman. Setiap permintaan tunggal yang mereka kirim ke layanan web akan menyertakan nama pengguna dan kata sandi, mungkin dalam bentuk otentikasi HTTP Basic , karena layanan yang RESTful tidak diizinkan untuk mempertahankan status klien dari satu permintaan ke yang berikutnya. Karena layanan web menggunakan HTTP aman, kata sandi dienkripsi dengan aman selama transit.
- Layanan web di
https://example.com/api
menerima banyak permintaan individu, masing-masing dengan informasi otentikasi. Nama pengguna dan kata sandi dalam setiap permintaan diperiksa terhadap basis data pengguna dan jika ditemukan benar, fungsi yang diminta dijalankan dan data dikembalikan ke klien dalam format JSON. Jika nama pengguna dan kata sandi tidak cocok dengan kesalahan dikirim ke klien dalam bentuk kode kesalahan HTTP 401.
- Alih-alih memaksa klien untuk mengirim nama pengguna dan kata sandi dengan setiap permintaan, Anda dapat memiliki fungsi "get_access_token" di layanan RESTful Anda yang mengambil nama pengguna dan kata sandi dan merespons dengan token, yang merupakan semacam hash kriptografi yang unik dan memiliki kedaluwarsa tanggal yang terkait dengannya. Token ini disimpan dalam database dengan setiap pengguna. Kemudian klien mengirimkan token akses dalam permintaan berikutnya. Token akses kemudian akan divalidasi terhadap basis data alih-alih nama pengguna dan kata sandi.
- Aplikasi klien non browser seperti aplikasi telepon melakukan hal yang sama seperti di atas, mereka meminta pengguna untuk memasukkan kredensial mereka, kemudian mengirimkannya (atau token akses yang dihasilkan dari mereka) dengan setiap permintaan ke layanan web.
Poin penting yang diambil dari contoh ini adalah bahwa layanan web RESTful memerlukan otentikasi dengan setiap permintaan .
Lapisan keamanan tambahan dalam skenario ini akan menambahkan otorisasi aplikasi klien selain otentikasi pengguna. Misalnya, jika Anda memiliki aplikasi klien web, iOS dan Android semua menggunakan layanan web, Anda mungkin ingin server mengetahui mana dari ketiga klien dari permintaan yang diberikan, terlepas dari siapa pengguna yang diautentikasi. Ini dapat memungkinkan layanan web Anda untuk membatasi fungsi tertentu untuk klien tertentu. Untuk ini, Anda bisa menggunakan kunci API dan rahasia, lihat jawaban ini untuk beberapa ide tentang itu.
Otentikasi Facebook
Alur kerja di atas tidak berfungsi untuk koneksi Facebook karena login melalui Facebook memiliki pihak ketiga, Facebook sendiri. Prosedur masuk mengharuskan pengguna untuk diarahkan ke situs web Facebook di mana kredensial dimasukkan di luar kendali kami.
Jadi mari kita lihat bagaimana hal berubah:.
- Pengguna terhubung ke
https://example.com
- Server menyajikan aplikasi Javascript yang kaya yang merender halaman awal. Di halaman tersebut ada formulir login yang menyertakan tombol "Login dengan Facebook".
- Pengguna mengklik tombol "Masuk dengan Facebook", yang hanya berupa tautan yang dialihkan ke (misalnya)
https://example.com/auth/facebook
.
- The
https://example.com/auth/facebook
rute ditangani oleh passport.js (lihat dokumentasi )
- Semua yang dilihat pengguna adalah bahwa halaman berubah dan sekarang mereka berada di halaman yang dihosting Facebook di mana mereka perlu login dan mengotorisasi aplikasi web kami. Ini sepenuhnya di luar kendali kami.
- Pengguna masuk ke Facebook dan memberikan izin ke aplikasi kami, jadi Facebook sekarang mengarahkan kembali ke URL panggilan balik yang kami konfigurasikan di pengaturan passport.js, yang mengikuti contoh dalam dokumentasi ini adalah
https://example.com/auth/facebook/callback
- Handler passport.js untuk
https://example.com/auth/facebook/callback
rute akan memanggil fungsi panggilan balik yang menerima token akses Facebook dan beberapa informasi pengguna dari Facebook, termasuk alamat email pengguna.
- Dengan email kami dapat menemukan pengguna di basis data kami dan menyimpan token akses Facebook dengannya.
- Hal terakhir yang Anda lakukan dalam panggilan balik Facebook adalah mengarahkan kembali ke aplikasi klien yang kaya, tetapi kali ini kami harus meneruskan nama pengguna dan token akses ke klien agar dapat menggunakannya. Ini dapat dilakukan dengan beberapa cara. Misalnya, variabel Javascript dapat ditambahkan ke halaman melalui mesin template sisi-server, atau cookie dapat dikembalikan dengan informasi ini. (terima kasih kepada @RyanKimber karena menunjukkan masalah keamanan dengan meneruskan data ini di URL, seperti yang saya sarankan pada awalnya).
- Jadi sekarang kita memulai aplikasi satu halaman sekali lagi, tetapi klien memiliki nama pengguna dan token akses.
- Aplikasi klien dapat memicu acara "masuk" dengan segera dan membiarkan berbagai bagian aplikasi meminta informasi yang mereka butuhkan dari layanan web.
- Semua permintaan yang dikirim
https://example.com/api
akan menyertakan token akses Facebook untuk otentikasi, atau token akses aplikasi sendiri yang dihasilkan dari token Facebook melalui fungsi "get_access_token" di REST API.
- Aplikasi non-browser sedikit lebih sulit di sini, karena OAuth membutuhkan browser web untuk masuk. Untuk masuk dari ponsel atau aplikasi desktop, Anda harus memulai browser untuk melakukan pengalihan ke Facebook, dan yang lebih buruk, Anda perlu cara bagi browser untuk melewatkan token akses Facebook kembali ke aplikasi melalui beberapa mekanisme.
Saya harap ini menjawab sebagian besar pertanyaan. Tentu saja Anda dapat mengganti Facebook dengan Twitter, Google, atau layanan otentikasi berbasis OAuth lainnya.
Saya akan tertarik untuk mengetahui apakah seseorang memiliki cara yang lebih sederhana untuk menghadapi ini.
passport-facebook
. Setelah Anda berhasil, langkah selanjutnya adalah mulai memahami cara kerja Paspor, dan cara menyimpan kredensial. Menyambungkannya ke Restify ( lihat di sini untuk versi terbaru dari yang Anda sebutkan) akan menjadi salah satu langkah terakhir (atau Anda bisa mengimplementasikan antarmuka REST di Express).