Arsitektur untuk menggabungkan beberapa akun pengguna bersama

176

Oke, saya punya situs web tempat Anda bisa mendaftar dan masuk. Anda juga dapat masuk dengan akun Facebook, twitter, atau tertaut Anda.

Adalah penting bahwa pengguna hanya memiliki satu akun terdaftar. Jadi, entah bagaimana, saya ingin menggabungkan akun pengguna jika mereka menggunakan metode berbeda untuk masuk. Apa solusi terbaik untuk menyelesaikan ini?

Misalnya, pengguna masuk dengan akun Facebook-nya. Saya menggunakan data untuk mendaftarkan akun untuknya secara otomatis. Haruskah saya mengirim email dengan nama pengguna dan kata sandi situs web kami? (Jika ini tidak masalah dengan kebijakan Facebook). Haruskah saya memberi mereka layar kedua di mana mereka dapat mengisi nama pengguna dan kata sandi? Tapi itu bukan ide di balik masuk dengan akun Facebook Anda. Ini harus menyederhanakan prosedur Anda untuk berpartisipasi.

Mungkin juga pengguna telah mendaftarkan dirinya di situs web kami dan saat berikutnya ia masuk dengan akun twitter-nya. Bagaimana saya bisa menggabungkan 2 akun ini sebagai satu? Apa cara terbaik?

Jadi pada dasarnya pertanyaan saya adalah: Saya punya 4 cara pengguna menjadi anggota situs web kami. Bagaimana saya bisa memastikan semua 4 cara ini hanya membuat satu akun jika pengguna memutuskan untuk menggunakan beberapa cara? Apa aliran terbaik untuk memastikan itu tidak menjadi masalah bagi pengguna sendiri?


Edit:

3 tahun setelah saya mengajukan pertanyaan ini, saya memberikan jawabannya sendiri dalam serangkaian artikel: https://www.peternijssen.nl/social-network-authentication-setup/
https://www.peternijssen.nl/social- network-authentication-google /
https://www.peternijssen.nl/social-network-authentication-merging-accounts/
https://www.peternijssen.nl/social-network-authentication-twitter-facebook/

PT
sumber
7
Tentu saja yang terbaik adalah mencoba untuk mencegah pengguna memiliki banyak akun di tempat pertama dengan mengizinkan beberapa metode login seperti Stack Overflow, tetapi bahkan SO memiliki kemampuan moderator untuk menggabungkan akun. Saya menawarkan hadiah bagi siapa saja yang dapat mendeskripsikan arsitektur untuk memungkinkan ini. Harus ada solusi yang lebih baik daripada "memperbarui set posting UserID = 2 di mana UserID = 1"
David Boike
email dan telepon dapat digunakan sebagai kunci penggabungan, yang lainnya?
Wuaner
Halo, tautan yang Anda berikan tampaknya tidak berfungsi. Ia pergi ke beranda situs saja
vigamage
Memperbarui tautannya. Artikel sudah berumur 6 tahun.
PT

Jawaban:

120

Saya dihadapkan dengan tugas yang sama saat ini. Desain yang saya kerjakan agak sederhana, tetapi bekerja dengan baik.

Gagasan intinya adalah bahwa model untuk identitas situs lokal dan identitas situs pihak ketiga tetap terisolasi, tetapi kemudian ditautkan. Jadi setiap pengguna yang masuk ke situs memiliki identitas lokal yang memetakan ke sejumlah identitas situs pihak ketiga.

Catatan identitas lokal berisi informasi minimum - bahkan bisa berupa bidang tunggal - hanya kunci utama. (Untuk aplikasi saya, saya tidak peduli dengan email, nama, atau tanggal lahir pengguna - Saya hanya ingin tahu mereka adalah orang yang telah masuk ke akun ini selama ini.)

Identitas pihak ketiga berisi informasi yang hanya relevan dengan otentikasi dengan pihak ketiga. Untuk OAuth, ini biasanya berarti pengidentifikasi pengguna (seperti id, email, atau nama pengguna) dan pengidentifikasi layanan (menunjukkan situs atau layanan apa yang diautentikasi). Di bagian lain aplikasi, di luar database, pengidentifikasi layanan dipasangkan dengan metode untuk mengambil pengenal pengguna yang relevan dari layanan itu, dan itulah cara otentikasi dilakukan. Untuk OpenID, kami menggunakan pendekatan yang sama, kecuali metode untuk otentikasi lebih digeneralisasi (karena kami hampir selalu dapat melakukan protokol yang sama persis - kecuali kami menggunakan URL identitas yang berbeda, dan itu adalah pengidentifikasi layanan kami).

Akhirnya, saya menyimpan catatan identitas pihak ketiga mana yang dipasangkan dengan identitas lokal apa. Untuk menghasilkan catatan ini, alirannya terlihat seperti ini:

  • Pengguna masuk untuk pertama kalinya menggunakan identitas pihak ketiga. Catatan identitas lokal dibuat, kemudian catatan identitas pihak ketiga, dan kemudian dipasangkan.
  • Di panel kontrol, pengguna ditawari kesempatan untuk menautkan akun dengan masuk ke layanan pihak ketiga. (Cukup jelas bagaimana ini bekerja.)
  • Dalam skenario di mana pengguna tanpa disadari membuat banyak akun, solusinya cukup sederhana. Ketika pengguna masuk di salah satu akun, ia masuk ke akun lain yang sebelumnya digunakan untuk masuk ke situs (melalui fitur panel kontrol di atas). Layanan web mendeteksi tabrakan ini (bahwa identitas lokal pengguna yang masuk berbeda dari identitas lokal yang ditautkan dengan identitas pihak ketiga yang baru saja masuk) dan pengguna diminta dengan penggabungan akun.

Menggabungkan akun adalah masalah menggabungkan setiap bidang individu dari identitas lokal (yang akan bervariasi dari satu aplikasi ke aplikasi lainnya, dan akan mudah jika Anda hanya memiliki beberapa bidang dalam catatan identitas lokal Anda), dan kemudian memastikan identitas pihak ketiga yang ditautkan terkait dengan identitas lokal yang dihasilkan.

pipi
sumber
1
Ini adalah solusi yang sangat bagus (Saya suka gagasan mendeteksi otomatis tabrakan identitas lokal)! Saya ingin tahu apakah Anda menemukan cara untuk masuk secara otomatis ke akun "ekstra" yang ditautkan setelah masuk pertama kali ke dalam aplikasi. Apakah pengguna harus login secara terpisah ke setiap akun setiap kali mereka mengunjungi (jika belum ada sesi aktif dengan penyedia ini)?
Alexandra
@Alexandra Apa yang Anda maksud dengan "akun ekstra"? Apakah Anda bertanya apa yang terjadi ketika pengguna masuk ke aplikasi melalui beberapa autentikator berbeda, membuat identitas lokal baru dengan masing-masing?
cheeken
Saya kira ini menjamin klarifikasi yang tepat dan pertanyaannya sendiri: stackoverflow.com/questions/11060368/…
Alexandra
3
Pertanyaannya, tetapi bagaimana jika pengguna mendaftar ke situs menggunakan alamat email yang sama? apakah kami meminta mereka bahwa email sudah ada (Email yang berasal dari model pihak ketiga) atau kami masih mendaftarkannya ke situs dan kemudian kami menggabungkan akun-akun itu?
user962206
@ user962206 banyak layanan tidak akan memberikan Anda alamat email 'nyata' karena alasan privasi. Misalnya, Twitter tidak akan memberi Anda alamat email apa pun, sejauh yang saya tahu Facebook akan memberikan "[email protected]" yang saya ragu seseorang akan gunakan untuk pendaftaran.
kapex
44

Saya cenderung menemukan banyak situs yang bergabung berdasarkan email sebagai faktor bergabung yang tumpang tindih.

Saya bisa melihat ini menjadi opsi yang layak, tetapi sekali lagi itu tergantung pada preferensi Anda tentang cara menggabungkan. Alamat Email adalah cara utama yang digunakan orang untuk memverifikasi beberapa perubahan informasi penting di situs Anda seperti, mengubah kata sandi, penghentian layanan, saldo akun rendah dll ... Ini hampir seperti sistem nomor jaminan sosial web tetapi dengan kemampuan komunikasi . Secara budaya: Saya pikir masuk akal untuk menganggap bahwa email adalah identitas yang cukup unik di seluruh layanan otentikasi OAuth. Memang, itulah yang diminta formulir masuk untuk Facebook dan Google.

Proses pemikiran saya saat ini.

Halaman login memiliki 3 opsi

  • Keanggotaan situs Anda sendiri
  • Masuk dengan Facebook
  • Login dengan google

1) Login pengguna untuk pertama kalinya: memicu aliran pendaftaran tempat akun dibuat dan diisi untuk pertama kalinya.

 if the user logins using Facebook (or whatever 3rd party login)
      1) call the Facebook api asking for their information (email, name, etc...) 
      2) create an account membership entry in your database somewhat like this 

         Table = Users
         [ UserId   |       Email             | Password ]
         [    23     | "[email protected]" |  *null*  ]

      3) create an external auths entry like so
         *ProviderUserId is the unique id of that user on the provider's site

         Table = ExternalAuths
         [ ExternalAuthId  |  User_UserId   | ProviderName |   ProviderUserId  ]
         [    56           |      23        |   Facebook   |  "max.alexander.9"]

 if the user wants to create an account with your own registration it would just be this           

         Table = Users
         [ UserId   |       Email           |   Password  ]
         [    23     | [email protected] |  myCoolPwd  ]

2) Di lain waktu, pengguna kembali tetapi memutuskan untuk mengklik Google Login

      1) call the Google api asking for their information (email, name, etc...) 

      2) once you get the email, match it up to the userId entry with the existing email 

      3) create an additional External auth entry as such

         Table = ExternalAuths
         [ ExternalAuthId  |  User_UserId   | ProviderName |   ProviderUserId  ]
         [    56           |      23        |   Facebook   |  "max.alexander.9"]
         [    57           |      23        |    Google    |  "1234854368"     ]

3) Sekarang Anda telah bergabung pada akun yang Anda percayai email pada entri database Anda sama dengan yang Anda percayai dari login eksternal.

Jadi untuk login selanjutnya

Jadi bagaimana jika Anda memiliki login eksternal terlebih dahulu dan kemudian Anda ingin pengguna dapat login dengan kata sandi nanti?

Saya melihat dua cara mudah untuk melakukan ini

  • Pada setiap login pertama saat akun dibuat dari auth eksternal, minta mereka untuk kata sandi untuk menyelesaikan entri pertama mereka ke dalam aplikasi Anda

  • Jika mereka sudah mendaftar menggunakan facebook atau google terlebih dahulu maka entah bagaimana ingin mendaftar menggunakan formulir pendaftaran situs Anda sendiri. Mendeteksi apakah alamat email yang mereka masukkan sudah ada, minta kata sandi, dan kirim mereka konfirmasi email setelah pendaftaran selesai.

Max Alexander
sumber
1
Ketika Anda menggunakan skema otentikasi eksternal (Facebook, Google, Twitter dll ...) Anda tidak akan pernah memiliki akses ke kata sandi penyedia eksternal. Kata sandi dalam contoh di atas adalah kata sandi untuk aplikasi web SENDIRI Anda.
Max Alexander
6
Twitter tidak menawarkan email kepada pengguna. Jadi setelah otentikasi pertama mereka jika UserId Twitter tidak ada, minta dia untuk email dan kata sandi. Jika email dan kata sandi ada, tautkan akun tersebut. Jika tidak, simpan email dan kata sandi untuk otentikasi berikutnya yang mulus. Apakah itu membantu sama sekali?
Max Alexander
1
Sebagai catatan tambahan, sekarang dimungkinkan untuk meminta izin untuk aplikasi Twitter Anda untuk mendapatkan alamat email pengguna.
Sunil D.
2
Apakah facebook membuat orang memverifikasi email mereka? Saya tahu bahwa Github, misalnya, tidak. Seorang pengguna jahat dapat mendaftar untuk Github dengan nama email orang lain dan kemudian mendapatkan akses ke akun mereka di situs Anda dengan strategi ini. (API Github memberi tahu Anda apakah email mereka diverifikasi atau tidak - Anda dapat menolak siapa pun yang mengautentikasi dengan Github pada alamat email yang tidak diverifikasi)
Matthew Moisen
6
Ini adalah pelanggaran keamanan jika pengguna mendaftar melalui media sosial, mengedit alamat email mereka di media sosial, orang lain mengambil alamat email yang sama, terdaftar dengan media sosial, dan kemudian login, mereka akan digabung dengan akun orang lain. Ini sangat tidak mungkin tetapi sebuah pelanggaran tidak kurang. Atau apakah saya melewatkan sesuatu.
Shane
35

Saya telah melalui ini dengan sled.com. Ada beberapa masalah di sini terkait dengan pembuatan akun dan mendukung beberapa akun pihak ketiga untuk login. Beberapa dari mereka adalah:

  • Apakah Anda perlu mendukung kata sandi lokal dan login pihak ketiga?

Untuk sled.com, saya telah memutuskan untuk menghapus kata sandi lokal karena nilai yang ditambahkannya kecil dan biaya tambahan dalam mengamankan formulir entri kata sandi. Ada banyak serangan yang dikenal karena melanggar kata sandi dan jika Anda akan memperkenalkan kata sandi, Anda harus memastikannya tidak mudah dipecahkan. Anda juga perlu menyimpannya dalam hash satu arah atau yang serupa untuk mencegahnya bocor.

  • Berapa banyak fleksibilitas yang ingin Anda izinkan dalam mendukung beberapa akun pihak ketiga?

Sepertinya Anda sudah memilih tiga penyedia login: Facebook, Twitter, dan LinkedIn. Itu bagus karena itu berarti Anda menggunakan OAuth dan bekerja dengan satu set penyedia tepercaya yang terdefinisi dengan baik. Saya bukan penggemar OpenID. Pertanyaan yang tersisa adalah apakah Anda perlu mendukung beberapa akun pihak ketiga dari penyedia yang sama (mis. Satu akun lokal dengan dua akun Twitter yang ditautkan). Saya berasumsi tidak, tetapi jika Anda melakukannya, Anda harus mengakomodasi itu dalam model data Anda.

Untuk Sled, kami mendukung login dengan Facebook, Twitter, dan Yahoo! dan di dalam setiap akun pengguna menyimpan kunci untuk masing-masing: {"_id": "djdjd99dj", "yahoo": "dj39djdj", twitter: "3723828732", "facebook": "12837287"}. Kami menyiapkan banyak kendala untuk memastikan bahwa setiap akun pihak ketiga hanya dapat ditautkan ke satu akun lokal.

Jika Anda akan mengizinkan beberapa akun dari penyedia pihak ketiga yang sama, Anda perlu menggunakan daftar atau struktur lain untuk mendukungnya, dan dengan itu, semua pembatasan lain untuk memastikan keunikan.

  • Bagaimana cara menautkan banyak akun?

Pertama kali pengguna mendaftar untuk layanan Anda, mereka pertama-tama pergi ke penyedia pihak ketiga dan kembali dengan id pihak ketiga yang terverifikasi. Anda kemudian membuat akun lokal untuk mereka dan mengumpulkan informasi apa pun yang Anda inginkan. Kami mengumpulkan alamat email mereka dan juga meminta mereka untuk memilih nama pengguna lokal (kami mencoba mengisi ulang formulir dengan nama pengguna yang ada dari penyedia lain). Memiliki beberapa bentuk pengenal lokal (email, nama pengguna) sangat penting untuk pemulihan akun nanti.

Server tahu ini adalah login pertama kali jika browser tidak memiliki cookie sesi (valid atau kedaluwarsa) untuk akun yang ada, dan bahwa akun pihak ketiga yang digunakan tidak ditemukan. Kami mencoba memberi tahu pengguna bahwa mereka tidak hanya masuk, tetapi membuat akun baru sehingga jika mereka sudah memiliki akun, mereka diharapkan akan berhenti sebentar dan masuk dengan akun mereka yang sudah ada.

Kami menggunakan aliran yang sama persis untuk menautkan akun tambahan, tetapi ketika pengguna kembali dari pihak ketiga, keberadaan cookie sesi yang valid digunakan untuk membedakan antara upaya untuk menautkan akun baru ke tindakan login. Kami hanya mengizinkan satu akun pihak ketiga dari setiap jenis dan jika sudah ada satu yang tertaut, blokir tindakan tersebut. Seharusnya tidak menjadi masalah karena antarmuka untuk menautkan akun baru dinonaktifkan jika Anda sudah memiliki satu (per penyedia), tetapi untuk berjaga-jaga.

  • Bagaimana cara menggabungkan akun?

Jika pengguna mencoba menautkan akun pihak ketiga baru yang sudah ditautkan ke akun lokal, Anda cukup meminta mereka untuk mengkonfirmasi bahwa mereka ingin menggabungkan kedua akun tersebut (dengan asumsi Anda dapat menangani penggabungan tersebut dengan kumpulan data Anda - seringkali lebih mudah dikatakan daripada dilakukan). Anda juga dapat memberi mereka tombol khusus untuk meminta penggabungan tetapi dalam praktiknya, yang mereka lakukan hanyalah menautkan akun lain.

Ini adalah mesin negara yang cukup sederhana. Pengguna kembali dari pihak ketiga dengan id akun pihak ketiga. Database Anda bisa di salah satu dari tiga negara:

  1. Akun ini ditautkan ke akun lokal dan tidak ada cookie sesi -> Login
  2. Akun tersebut ditautkan ke akun lokal dan cookie sesi hadir -> Gabung
  3. Akun tidak tertaut ke akun lokal dan tidak ada cookie sesi -> Daftar
  4. Akun tidak tertaut ke akun lokal dan cookie sesi hadir -> Menautkan akun tambahan

    • Bagaimana cara melakukan pemulihan akun dengan penyedia pihak ketiga?

Ini masih merupakan wilayah percobaan. Saya belum melihat UX yang sempurna untuk ini karena sebagian besar layanan menyediakan kedua kata sandi lokal di sebelah akun pihak ketiga dan oleh karena itu fokus pada kasus penggunaan "forget my password", bukan semua hal lain yang bisa salah.

Dengan Sled, kami memilih untuk menggunakan "Perlu bantuan masuk?" dan ketika Anda mengklik, minta pengguna untuk email atau nama pengguna mereka. Kami mencarinya dan jika kami menemukan akun yang cocok, kirim tautan tersebut melalui email kepada pengguna yang secara otomatis dapat memasukkan mereka ke dalam layanan (baik untuk satu kali). Setelah masuk, kami membawanya langsung ke halaman yang menghubungkan akun, memberi tahu mereka bahwa mereka harus melihat dan berpotensi menautkan akun tambahan, dan menunjukkan kepada mereka akun pihak ketiga yang telah mereka tautkan.

Eran Hammer
sumber
Solusi ini jauh lebih baik untuk saya, Terima kasih!
Roy Shoa
2
Cookie sesi tidak cukup baik untuk mengidentifikasi pengguna. Bagaimana jika pengguna lain menggunakan perangkat yang sama?
DeepBlue
23

Kedua pendekatan untuk menggabungkan akun secara otomatis meninggalkan kerentanan yang cukup besar yang akan memungkinkan seseorang untuk mengambil alih akun. Mereka berdua tampaknya membuat asumsi bahwa pengguna adalah yang mereka katakan ketika mereka menawarkan opsi penggabungan kepada pengguna yang mendaftar.

Rekomendasi saya untuk mengurangi kerentanan adalah meminta pengguna untuk mengotentikasi dengan salah satu Penyedia Identitas yang dikenal sebelum melakukan penggabungan untuk memverifikasi identitas pengguna.

Contoh: Pengguna A mendaftar dengan identitas Facebook. Beberapa waktu kemudian mereka kembali ke situs Anda dan mencoba mengakses dengan Windows Live ID dan memulai proses pendaftaran. Situs Anda akan meminta Pengguna A dengan ... Sepertinya Anda telah terdaftar di Facebook sebelumnya. Silakan masuk dengan Facebook (berikan tautan) dan kami dapat menggabungkan Windows Live ID Anda dengan profil Anda yang ada.

Alternatif lain adalah menyimpan rahasia bersama (kata sandi / pertanyaan pribadi) pada pendaftaran awal yang harus disediakan pengguna saat menggabungkan identitas, namun ini membuat Anda kembali ke bisnis penyimpanan rahasia bersama. Ini juga berarti Anda harus menangani skenario di mana pengguna tidak mengingat rahasia bersama dan alur kerja yang menyertainya.

Brad J
sumber
apa yang Anda lakukan jika Anda tidak menerima alamat email dari penyedia?
fred.kassi
1

Sebagian besar posting sudah cukup lama dan saya kira layanan Firebase Authentication gratis Google belum ada. Setelah memverifikasi dengan OAuth, Anda meneruskan token OAuth ke sana dan mendapatkan id pengguna unik yang dapat Anda simpan untuk referensi. Penyedia yang didukung adalah Google, Facebook, Twitter, GitHub dan ada opsi untuk mendaftar penyedia kustom dan anonim.

galki
sumber
Ada beberapa kasus penggunaan yang dianggap sebagai firebase tidak masuk akal. Misalnya sistem intranet yang memiliki lebih dari satu login ..
Bostwick
-4

Anda harus mengizinkan masuk dari satu akun, lalu ketika masuk, berikan opsi untuk menambahkan akun lain yang berbeda untuk bergabung dengannya.

Naftali alias Neal
sumber
4
Dan apa yang terjadi jika pengguna tidak melakukan itu, dan mendapati dirinya dengan 4 akun berbeda? Bagaimana Anda membuat arsitektur yang memungkinkan penggabungan dalam kasus ini?
David Boike
Tergantung pada kebutuhan Anda, ini sebenarnya bisa menjadi saran yang valid. Saya hanya ingin memperingatkan mereka yang berpikir bahwa menggabungkan atau menautkan akun dapat dilakukan nanti sebagai setelah-meskipun: Jika Anda percaya ini adalah sesuatu yang Anda inginkan nanti maka Anda ingin mempersiapkan diri untuk itu pada awalnya dengan desain database Anda: Satu opsi adalah memiliki UserGroup dan Pemetaan Pengguna. Anda bisa memetakan ID pengguna OAuth atau ID pengguna Email & Kata Sandi ke UserGroup.
BumbleB2na