Desain untuk otentikasi Facebook di aplikasi iOS yang juga mengakses layanan web aman

402

Sasaran: Memungkinkan pengguna untuk otentikasi dengan Facebook ke dalam aplikasi iOS yang membutuhkan akses ke layanan web yang dilindungi yang saya jalankan.

Asumsi: Terdapat sistem autentikasi asli (dan pendaftaran) untuk pengguna yang memilih untuk tidak menggunakan Facebook untuk masuk.

Detail:

  • Asumsikan kami ingin menawarkan opsi bagi pengguna untuk masuk dengan Facebook tanpa membuat akun / kredensial terpisah untuk sistem kami.
  • Karena kami mendukung mekanisme autentikasi asli kami sendiri (nama pengguna dan kata sandi) kami memiliki ID pengguna kami sendiri dan mengeluarkan token otentikasi yang digunakan untuk interaksi berikutnya setelah validasi kredensial awal.

Saya terkejut bahwa Facebook tidak memiliki praktik terbaik untuk ini dalam dokumentasi pengembang mereka. Semua dokumentasi yang ada mengasumsikan Anda sedang membangun FB auth ke situs web, atau aplikasi seluler mandiri tanpa layanan yang memerlukan otentikasi.

Inilah pemikiran awal saya tentang bagaimana ini akan dirancang tetapi ingin validasi apakah itu benar.

  1. Klien membuka Facebook iOS Login
  2. Pengguna UI masuk dengan kredensial Facebook dan mendapat token akses
  3. Aplikasi iOS memberikan token akses ke server kami
  4. Server kami berbicara dengan FB graph API menggunakan token akses ke (a) memvalidasi token dan (b) mendapatkan ID pengguna FB untuk token akses itu.

    mis. Server kami akan memanggil https://graph.facebook.com/me/?access_token=XYZ yang akan mengembalikan info profil dalam objek JSON

  5. Dengan asumsi itu valid, server kami mengekstrak ID Pengguna dari objek JSON dan memeriksa apakah pengguna sudah memiliki akun. Jika demikian, kami mengeluarkan tiket autentikasi kami sendiri ke klien untuk digunakan untuk sesi itu. Jika pengguna tidak memiliki akun, kami membuat yang baru dengan ID Pengguna Facebook, menetapkan UserID unik kami sendiri dan mengeluarkan tiket autentikasi kami.

  6. Klien kemudian memberikan tiket auth kembali pada interaksi berikutnya yang perlu otentikasi.

Ini sepertinya pendekatan yang tepat untuk saya tetapi tidak yakin apakah saya melewatkan sesuatu yang sangat mendasar dan menuruni jalan yang salah (rumit).

TMC
sumber
1
Bagaimana ini diselesaikan? Saya melihat melewati token akses juga, dan memutar pengguna di server. Tampaknya akademis, tetapi saya bertanya.
Chris Van Buskirk
Ini adalah implementasi saya menggunakan rails dan merancang: stackoverflow.com/questions/7232490/…
Matt
Mengapa tidak meneruskan seluruh auth_hash daripada harus membuat dua panggilan ke FB API (satu dari perangkat iOS dan satu dari server)?
bsiddiqui
1
Bagaimana jika Anda ingin masuk dari perangkat lain (artinya Anda tidak memiliki tiket auth)? Dan jika Anda baru saja menerima tiket auth baru, apa yang mencegah seseorang membajak id / token di jalan dan menggunakannya pada perangkatnya sendiri?
Amitloaf
Karena penasaran, pada langkah 5, mengapa mengeluarkan tiket auth sendiri? Bisakah Anda tidak menggunakan token akses Facebook untuk setiap panggilan server berikutnya? Saya menyadari bahwa itu akan membutuhkan panggilan dari server ke Facebook API untuk setiap aplikasi -> panggilan server daripada hanya yang pertama.
Anders

Jawaban:

80

Saya hanya berurusan dengan ini sendiri, dan inilah bagian yang menggigit saya:

Di langkah 5 Anda ... Adalah mungkin bagi pengguna untuk mendaftar akun dengan Anda yang sepenuhnya terpisah dari ID Facebook mereka, bukan? Kemudian di lain waktu mereka masuk dengan Facebook .... Dan Anda baru saja membuat mereka akun kedua dan kehilangan yang pertama.

Perlu ada cara untuk masuk ke layanan web Anda, kemudian masuk ke Facebook, dan tangkap hubungan antara ID facebook dan akun lokal.

Terlepas dari itu, rencana Anda kedengarannya solid.

Pembaruan : Facebook telah menambahkan dokumen yang menguraikan skenario seperti ini DI SINI

Dan Ray
sumber
7
Yap, saya sudah mempertimbangkan itu dan Anda tepat. Kami berencana untuk menggabungkan akun jika alamat emailnya sama, dan jika tidak, kami akan membuat cara lain untuk menggabungkannya.
TMC
Pustaka Server mana yang Anda gunakan di sisi Server untuk membuat permintaan?
TimLeung
7
@TimLeung - Pemahaman saya adalah bahwa token akses menyematkan ID aplikasi, dan bahwa Anda tidak dapat memiliki token akses TANPA ID aplikasi dimasukkan ke dalamnya.
Dan Ray
1
@TimLeunge: Kami menggunakan Grafik API untuk permintaan dengan token akses pengguna.
TMC
29

Gunakan https untuk mengirimkan token autentikasi ke server Anda, seperti yang dinyatakan oleh Facebook

Berbagi Token Akses

Kebijakan Data kami secara eksplisit melarang berbagi Token Akses untuk aplikasi Anda dengan aplikasi lain apa pun. Namun, kami mengizinkan pengembang untuk membagikan Token antara implementasi asli dan implementasi server dari Aplikasi yang sama (mis. Menggunakan ID Aplikasi yang sama) selama transfer berlangsung menggunakan HTTPS.

zoomcrypt
sumber
16

Satu masalah yang bisa saya lihat dengan strategi ini, adalah seseorang dapat memberi Anda token akses yang diperoleh untuk aplikasi facebook yang berbeda. Sejauh yang saya tahu, tidak ada cara untuk memverifikasi bahwa token akses adalah untuk aplikasi Anda, jadi Anda hanya akan melanjutkan dan menggunakannya.

Kedengarannya tidak berbahaya. Umumnya orang / aplikasi mencoba melindungi token akses, daripada membaginya.

Salah satu kemungkinan eksploitasi ini adalah, bagi seseorang untuk membuat situs atau aplikasi seluler mereka sendiri, memperoleh token akses untuk pengguna mereka dan mencoba untuk mengotentikasi mereka, menggunakan API Anda. Jika ini berhasil (pengguna memiliki akun facebook di situs Anda), situs jahat akan dapat menggunakan API Anda menyamar sebagai pengguna.

Ini agak sulit, tapi saya pikir itu bisa berhasil.

Sunting: Sepertinya ada cara untuk memvalidasi token akses. Lihat jawaban oleh @Daaniel pada pertanyaan Dapatkan id aplikasi dari token akses pengguna (atau verifikasi aplikasi sumber untuk token) .

ivant
sumber
Mengirim appsecret_proofharus mencegah hal ini (lihat di sini )
Tony
@ Tony, bisakah Anda menjelaskan bagaimana appsecret_proofmembantu di sini? Sejauh yang saya mengerti, ini berfungsi untuk membuktikan kepada Facebook bahwa server mengetahui kunci rahasia. Namun, ivant merujuk ke aplikasi jahat yang mendapatkan token dan kemudian mengirimkannya ke API Anda. Server dapat memverifikasi ID aplikasi, tetapi ID aplikasi dapat dengan mudah dipalsukan oleh aplikasi jahat. Jadi ... bagaimana kita mengurangi ini?
YSK
3
Anda dapat memverifikasi bahwa token yang dihasilkan untuk aplikasi Anda melalui https://graph.facebook.com/app/?access_token=[user_access_token]mana mengembalikan id aplikasi, dan kemudian membandingkan id aplikasi
Nader Alexan
4

solusi Anda benar-benar berfungsi.

Mungkin alternatif: mengapa tidak hanya mendapatkan email pada klien dari permintaan layanan sosial awal dan mengirim ke layanan web Anda? Layanan web bisa menyimpan email, dan mungkin social_provider juga. Saya memahami bahwa layanan web Anda tidak akan dapat memvalidasi dari mana email itu berasal, tetapi tidakkah ada hubungan saling percaya yang tinggi antara layanan web Anda dan klien Anda? Jika ada, sepertinya Anda bisa bergantung pada email yang datang dari tempat yang tepat. Seseorang tolong beri tahu saya apa hal jelas yang saya lewatkan yang membuat pendekatan berbasis email ini konyol ...

hamsterdam
sumber
3
Saya dapat dengan mudah mengetahui bagaimana klien berbicara dengan server. Kemudian saya bisa mengirim email padanya sampai saya mendapatkan hit. Selalu perlu ada semacam verifikasi
Chris
5
Kepercayaan tinggi dan klien? Tolong, jangan pernah dalam kalimat yang sama. Kecuali tentu saja kalimat sebelumnya.
EralpB