複数のユーザーアカウントをマージするためのアーキテクチャ


176

さて、私はあなたがあなた自身を登録してログインできるウェブサイトを手に入れました。Facebook、Twitter、Linkedinアカウントでログインすることもできます。

ユーザーは1つのアカウントのみを登録することが重要です。どういうわけか、ユーザーが異なる方法でログインする場合は、ユーザーのアカウントをマージしたいと思います。これを解決する最善の解決策は何ですか?

たとえば、ユーザーは自分のFacebookアカウントでログインします。このデータを使用して、彼のアカウントを自動的に登録します。私たちのウェブサイトのユーザー名とパスワードをメールで送るべきですか?(これがFacebookのポリシーで問題ない場合)。ユーザー名とパスワードを入力できる2番目の画面を表示する必要がありますか?しかし、それはあなたのFacebookアカウントでログインする背後にある考えではありません。参加するための手続きが簡単になります。

また、ユーザーが当社のWebサイトに自分自身を登録し、次に彼のTwitterアカウントでログインすることもできます。これらの2つのアカウントを1つにマージするにはどうすればよいですか?最良の方法は何ですか?

だから基本的に私の質問は:ユーザーが私たちのウェブサイトのメンバーになる4つの異なる方法を得た。ユーザーが複数の方法を使用する場合、これらの4つの方法すべてが1つのアカウントのみを作成するようにするにはどうすればよいですか?ユーザー自身が面倒にならないようにするための最善のフローは何ですか?


編集:

私がこの質問をした3年後、一連の記事で自分自身で答えを出しています: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/


7
もちろん、Stack Overflowのような複数のログイン方法を許可することにより、ユーザーが最初に複数のアカウントを持つことを防ぐのが最善ですが、SOにもモデレーターがアカウントをマージする機能があります。これを可能にするアーキテクチャを説明できる人なら誰でも賞金を差し上げます。「Update post set UserID = 2 where UserID = 1」よりも優れたソリューションが必要です
David Boike

メールと電話はマージキーとして使用できますか?
Wuaner

こんにちは、あなたが提供したリンクは機能していないようです。サイトのホームページにのみ
アクセス

リンクを更新しました。記事は6歳です。
PT

回答:


120

私は今、まったく同じ仕事に直面しています。私が考え出したデザインはかなりシンプルですが、うまく機能します。

核となる考えは、ローカルサイトIDとサードパーティサイトIDのモデルは分離されたままですが、後でリンクされるということです。そのため、サイトにログインするすべてのユーザーは、任意の数のサードパーティのサイトIDにマップするローカルIDを持っています。

ローカルIDレコードには、最低限の情報が含まれています。単一のフィールドである場合もあり、主キーにすぎません。(私のアプリケーションでは、ユーザーのメールアドレス、名前、生年月日は関係ありません。彼らがこのアカウントにずっとログインしている人であることを知りたいだけです。)

サードパーティのIDには、サードパーティによる認証にのみ関連する情報が含まれています。OAuthの場合、これは通常、ユーザーID(ID、電子メール、ユーザー名など)とサービスID(認証されたサイトまたはサービスを示す)を意味します。アプリケーションの他の部分では、データベースの外で、そのサービスIDは、そのサービスから関連するユーザーIDを取得するメソッドとペアになっています。つまり、認証はこのように行われます。OpenIDの場合、認証の方法がより一般化されていることを除いて、同じアプローチを採用しています(異なるID URLを使用することを除いて、ほとんどの場合、まったく同じプロトコルを実行できるため、それがサービス識別子です)。

最後に、どのサードパーティのIDがどのローカルIDとペアリングされているかを記録します。これらのレコードを生成するためのフローは次のようになります。

  • ユーザーは、サードパーティのIDを使用して初めてログインします。ローカルIDレコードが作成され、次にサードパーティIDレコードが作成されて、ペアになります。
  • コントロールパネルでは、サードパーティのサービスにログインしてアカウントをリンクする機会が提供されます。(これがどのように機能するかはかなり簡単です。)
  • ユーザーが意図せずに複数のアカウントを作成するシナリオでは、解決策は非常に簡単です。ユーザーがいずれかのアカウントでログインしているときに、以前に(上記のコントロールパネル機能を使用して)サイトにログインするために使用した別のアカウントにログインします。Webサービスはこの衝突を検出し(ログインしたユーザーのローカルIDが、ログインしたばかりのサードパーティのIDにリンクされているローカルIDと異なる)、ユーザーはアカウントのマージを求められます。

アカウントのマージは、ローカルIDの個々のフィールドをマージすることです(アプリケーションごとに異なり、ローカルIDレコードにフィールドが2つしかない場合は簡単です)。次に、リンクされたサードパーティIDを確認します。結果のローカルIDにリンクされます。


1
これは非常に優れたソリューションです(ローカルIDの衝突を自動検出するというアイデアが気に入っています)。アプリケーションに最初にログインした後にリンクされている「追加」アカウントにユーザーを自動ログインする方法を見つけたのでしょうか。ユーザーはアクセスするたびに各アカウントに個別にログインする必要がありますか(このプロバイダーとのアクティブなセッションがない場合)。
Alexandra

@Alexandra「追加アカウント」とはどういう意味ですか?ユーザーが複数の異なる認証システムを介してアプリケーションにログインし、それぞれに新しいローカルIDを作成するとどうなるかを尋ねていますか?
チーケン、

:私はこの令状に適切な明確化し、独自の質問を推測stackoverflow.com/questions/11060368/...
アレクサンドラ

3
ただし、ユーザーが同じメールアドレスを使用してサイトに登録した場合はどうでしょうか。メールが既に存在することを通知するのですか(サードパーティモデルから送信されたメール)、それともサイトに登録した後、それらのアカウントを結合しますか?
user962206 2013

@ user962206多くのサービスでは、プライバシー上の理由から、「実際の」電子メールアドレスは提供されません。たとえば、Facebookが「user.name@facebook.com」を提供することを知っている限り、Twitterからメールアドレスが提供されることはありません。
kapex 2013

44

重複する結合要素として、多くのサイトがメールに基づいてマージする傾向があります。

私はこれが実行可能なオプションであると見ることができますが、やはりそれはマージする方法のあなたの好みに依存します。電子メールアドレスは、パスワードの変更、サービスの終了、アカウントの残高が少ないなど、サイトで重要な情報の変更を確認するために人々が使用する主な方法です。これは、Webの社会保障番号システムとほぼ同じですが、通信機能を備えています。文化的に:メールはOAuth認証サービス全体でかなりユニークなIDであると想定するのが妥当だと思います。確かに、それはFacebookとGoogleのログインフォームが要求するものです。

私の現在の思考プロセス。

ログインページには3つのオプションがあります

  • 自分のサイトのメンバーシップ
  • Facebookでログイン
  • グーグルでログイン

1)初めてのユーザーログイン:初めてアカウントが作成および入力される登録フローをトリガーします。

 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     | "newuser@coolmail.com" |  *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     | newuser@coolmail.com |  myCoolPwd  ]

2)ユーザーが戻ってきたが、Googleログインをクリックすることにした

      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)これで、データベースエントリの電子メールを信頼するアカウントにマージされました。外部ログインから信頼するものと同じです。

したがって、以降のログインでは

では、最初に外部ログインがあり、ユーザーが後でパスワードを使用してログインできるようにしたい場合はどうでしょうか。

これを行う簡単な方法が2つあります

  • 外部認証からアカウントが作成される最初のログイン時に、アプリケーションへの最初のエントリを完了するためにパスワードを要求します

  • 最初にFacebookまたはGoogleを使用してすでに登録している場合は、どういうわけか自分のサイトの登録フォームを使用して登録したいと考えていました。入力したメールアドレスが既に存在するかどうかを検出し、パスワードを要求し、登録が完了したら確認メールを送信します。


1
外部認証スキーム(Facebook、Google、Twitterなど)を使用する場合、外部プロバイダーのパスワードにアクセスすることはできません。上記の例のパスワードは、OWN Webアプリのパスワードです。
Max Alexander

6
Twitterはユーザーにメールを提供しません。したがって、TwitterのUserIdが存在しない場合は、最初の認証後に、メールとパスワードの入力を求めます。メールとパスワードが存在する場合は、アカウントをリンクします。そうでない場合は、後続のシームレスな認証のために電子メールとパスワードを保存します。役に立ちましたか?
Max Alexander

1
補足として、Twitterアプリがユーザーのメールアドレスを取得するための権限リクエストできるようになりました。
Sunil D.

2
Facebookは人々に自分のメールを確認させますか?たとえば、Githubはそうではないことを知っています。悪意のあるユーザーが他の誰かの電子メール名でGithubにサインアップし、この戦略を使用してサイトの自分のアカウントにアクセスする可能性があります。(GithubのAPIは、電子メールが検証済みかどうかを通知します-未検証の電子メールアドレスでGithubで認証されているユーザーを拒否できます)
Matthew Moisen

6
これは、ユーザーがソーシャルメディアを介してサインアップし、ソーシャルメディアで自分のメールアドレスを編集し、他の誰かがソーシャルメディアに登録された同じメールアドレスを取得してログインすると、セキュリティ違反となり、他の誰かのアカウントと結合されます。これは非常にまれですが、それでも違反はありません。それとも何か不足していますか?
シェーン

35

sled.comでこれを実行しました。ここでは、アカウントの作成とログイン用の複数のサードパーティアカウントのサポートに関して複数の問題があります。それらのいくつかは:

  • ローカルパスワードとサードパーティログインの両方をサポートする必要がありますか?

sled.comの場合、ローカルパスワードは値が小さいため、パスワードエントリフォームを保護するための追加コストがかかるため、削除することにしました。パスワードを解読するための多くの既知の攻撃があり、パスワードを導入する場合は、解読が容易でないことを確認する必要があります。また、リークを防ぐために、それらを一方向ハッシュなどに格納する必要があります。

  • 複数のサードパーティのアカウントをサポートする際にどの程度の柔軟性を許可したいですか?

Facebook、Twitter、LinkedInの3つのログインプロバイダーをすでに選択しているようです。これは、OAuthを使用し、明確に定義された信頼できるプロバイダーのセットを使用していることを意味するので、すばらしいことです。私はOpenIDのファンではありません。残りの問題は、同じプロバイダーの複数のサードパーティアカウントをサポートする必要があるかどうかです(たとえば、2つのTwitterアカウントがリンクされた1つのローカルアカウント)。私はそうではないと想定していますが、そうする場合は、それをデータモデルに組み込む必要があります。

Sledについては、Facebook、Twitter、Yahoo!でのログインをサポートしています。各ユーザーアカウント内に、それぞれのキーを保存します:{"_id": "djdjd99dj"、 "yahoo": "dj39djdj"、twitter: "3723828732"、 "facebook": "12837287"}。一連の制約を設定して、各サードパーティのアカウントが単一のローカルアカウントにのみリンクできるようにします。

同じサードパーティプロバイダーの複数のアカウントを許可する場合は、リストまたは他の構造を使用してそれをサポートする必要があります。これにより、他のすべての制限が一意性を確保します。

  • 複数のアカウントをリンクするには?

ユーザーが初めてサービスにサインアップするとき、ユーザーは最初にサードパーティプロバイダーにアクセスし、検証済みのサードパーティIDを返します。次に、それらのローカルアカウントを作成し、必要な他の情報を収集します。メールアドレスを収集し、ローカルのユーザー名を選択するよう依頼します(他のプロバイダーからの既存のユーザー名をフォームに事前に入力しようとします)。何らかの形でローカル識別子(電子メール、ユーザー名)を持っていることは、後でアカウントを回復するために非常に重要です。

サーバーは、ブラウザーに既存のアカウントのセッションCookie(有効または期限切れ)がない場合、これが初めてのログインであること、および使用されているサードパーティのアカウントが見つからないことを認識しています。ログインしているだけでなく、新しいアカウントを作成していることをユーザーに通知します。これにより、すでにアカウントを持っている場合は、代わりに一時停止して既存のアカウントでログインできます。

まったく同じフローを使用して追加のアカウントをリンクしますが、ユーザーがサードパーティから戻ってきたとき、有効なセッションCookieの存在を使用して、新しいアカウントをログインアクションにリンクする試みを区別します。許可されるのは、各タイプのサードパーティアカウント1つだけです。すでにリンクされているアカウントがある場合は、アクションをブロックします。新しいアカウントをリンクするためのインターフェースがすでにある場合は(プロバイダーごとに)、万が一のために無効になっているため、問題にはなりません。

  • アカウントをマージするには?

ユーザーが既にローカルアカウントにリンクされている新しいサードパーティのアカウントをリンクしようとした場合は、2つのアカウントをマージすることを確認するようにユーザーに促すだけです(データセットとのそのようなマージを処理できると仮定します-多くの場合、より簡単です)行われるより)。マージをリクエストするための特別なボタンを提供することもできますが、実際には、彼らがしていることはすべて別のアカウントをリンクすることです。

これはかなり単純な状態機械です。ユーザーはサードパーティのアカウントIDを使用してサードパーティから戻ってきます。データベースは、次の3つの状態のいずれかになります。

  1. アカウントはローカルアカウントにリンクされており、セッションCookieが存在しない->ログイン
  2. アカウントはローカルアカウントにリンクされ、セッションCookieが存在する->マージ
  3. アカウントがローカルアカウントにリンクされておらず、セッションCookieが存在しない->サインアップ
  4. アカウントはローカルアカウントにリンクされておらず、セッションCookieが存在します->追加のアカウントをリンクしています

    • サードパーティのプロバイダーでアカウントを回復するにはどうすればよいですか?

これはまだ実験的な領域です。ほとんどのサービスはサードパーティのアカウントの隣にローカルパスワードを提供しているため、「パスワードを忘れた」というユースケースに焦点を当てているため、完全なUXを見たことはありません。

スレッドでは、「サインインが必要ですか?」を使用することを選択しました。クリックしたときに、ユーザーにメールまたはユーザー名を尋ねます。調べて、一致するアカウントが見つかった場合は、そのユーザーにサービスに自動的にログインできるリンクをメールで送信します(1回限り有効)。いったん入力すると、アカウントリンクページに直接アクセスし、確認して追加のアカウントをリンクする可能性があることを伝え、すでにリンクしているサードパーティのアカウントを表示します。


このソリューションは私にとってはるかに優れています、ありがとう!
ロイショア2014

2
セッションCookieは、ユーザーを識別するのに十分ではありません。別のユーザーが同じデバイスを使用している場合はどうなりますか?
DeepBlue

23

アカウントを自動マージするための両方のアプローチには、誰かがアカウントを乗っ取ることができるかなり大きな脆弱性が残っています。どちらも、登録ユーザーにマージオプションを提供するときに、ユーザーは自分が本人であると想定しているようです。

脆弱性を緩和するための私の推奨は、マージを実行してユーザーのIDを確認する前に、既知のIDプロバイダーの1つでユーザー認証を要求することです。

例:ユーザーAがFacebook IDに登録します。しばらくすると、彼らはあなたのサイトに戻り、Windows Live IDでアクセスして登録プロセスを開始しようとします。サイトはユーザーAに次のメッセージを表示します...以前にFacebookに登録したようです。Facebookでログインしてください(リンクを提供)。WindowsLive IDを既存のプロファイルとマージできます。

別の方法は、ユーザーがIDをマージするときに提供する必要がある初期登録時に共有シークレット(パスワード/個人の質問)を保存することですが、これにより共有シークレットを保存するビジネスに戻ることができます。また、ユーザーが共有シークレットとそれに伴うワークフローを覚えていないシナリオを処理する必要があることも意味します。


プロバイダーからメールアドレスを受け取っていない場合はどうしますか?
fred.kassi

1

ほとんどの投稿はかなり古く、Googleの無料のFirebase Authenticationサービスはまだ存在していなかったと思います。OAuthで確認した後、OAuthトークンをそれに渡し、参照用に保存できる一意のユーザーIDを取得します。サポートされているプロバイダーは、Google、Facebook、Twitter、GitHubで、カスタムプロバイダーと匿名プロバイダーを登録するオプションがあります。


firebaseが意味をなさないと考えられるユースケースがあります。より、その後のログを持っている例のイントラネットシステムの場合...
ボストウィック


-4

1つのアカウントからのログインを許可し、ログイン時に別の別のアカウントを追加して、それをマージするオプションを提供する必要があります。


4
そして、ユーザーがそれを行わず、4つの異なるアカウントを自分で見つけた場合はどうなりますか?この場合、マージを可能にするアーキテクチャをどのように作成しますか?
David Boike、2011

ニーズによっては、これが実際に有効な提案になる場合があります。アカウントのマージまたはリンクは後で実行できると考える人に警告したいだけです。これが後で必要になる可能性があると思われる場合は、データベース設計で最初に準備する必要があります。オプションは、UserGroupとUserMappingを持つことです。OAuthユーザーIDまたはメールとパスワードのユーザーIDをUserGroupにマッピングできます。
BumbleB2na
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.