web-dev-qa-db-ja.com

認証にサードパーティ(Google、Facebook、Twitterなど)を使用するには、RESTful Webサービスをどのように設計すればよいですか?

私の仕事のために、私たちが構築した素敵なRESTful Webサービスを用意しました。基本的に、Webサービスを使用すると、サポートチケットを作成して操作でき、Webサイトはフロントエンドを担当します。すべてのWebサービス要求は、各呼び出しのユーザーとパスワードを検証するために使用する認証ヘッダーを使用します。

今年は、ログインオプションを拡張して、WebサイトのユーザーがGoogle、Twitter、Facebook(おそらく他のユーザー)経由でログインできるようにする予定です。ただし、これを構築する方法を理解するのに多くの問題があり、Webサービスがサードパーティの認証プロバイダーを使用して、ユーザーが本人であることを確認できます。これを行うためのベストプラクティスはありますか?

現在、ユーザーの認証をWebサイトで処理し、現在のセッションをWebサービスバックエンドに登録する新しいsetSessionId呼び出しを使用することを検討しています。 Webサービスへの追加の各リクエストは、そのsessionIdを渡し、それを検証します。これらは大丈夫のようですが、私はこれを熟考していないと頭の後ろに感じています。すべての私のフォーラムのブラウジングと閲覧oauthとopenidの仕様は私を混乱させています。これに取り組む方法のヒント?

25
Ralph Callaway

目標は2つあるようです。

  1. エンドユーザーが既存のソーシャルアカウントで認証するのが簡単
  2. Webサービスを使用する開発者にとって簡単

サイトのリソースを使用することを人々に許可すると、クライアントライブラリの人気と可用性により、OAuth2が推奨されるメカニズムになります。

1.エンドユーザーが既存のソーシャルアカウントで認証するのが簡単

エンドユーザーは、APIを使用するサイトにアクセスし、ログインすることを選択します。 OAuthログインページに送信されます。ログインページには、通常のユーザー名とパスワードが表示されます。サイトで管理されているアカウントのプロンプトと、サイトを介してクリックしてログインできるソーシャル認証ボタンのセットが表示されますFacebookのように、ユーザーがFacebookを選択すると、ユーザーはFacebookにリダイレクトされて選択が承認されます(Facebookの認証フローが開始されます)。エンドユーザーがFacebookへのログインを完了すると、サイトにリダイレクトされます。

ユーザーがFacebookからサイトにリダイレクトされると、そのユーザーの情報がデータベースのユーザーレコードに保存され、そのユーザーの新しいセッションが生成されます。 oauth access_tokenを使用して、エンドユーザーをすぐに元のダウンストリームサイトにリダイレクトし、元のoauthフローを完了します。

2.ウェブサービスを使用する開発者にとって簡単

承認のプロバイダーである場合は、開発者が依存するシンプルなインターフェイスを作成する必要があります。これは、oauthを完全に実装していない新しいアップストリーム認証プロバイダーを追加するたびに変更されません。これはOAuth2プロバイダーサイトを実装する必要があり、そのサイトがソーシャル認証サイトのコンシューマーである必要があると私が考える理由です。

ナイスレストAPIを使用している開発者にとって、セッションキャプチャの投稿を通じてヒントを与えることを選択しない限り、開発者はFacebookの相互作用を認識しません。

TL; DR

OAuth2を実装し、ソーシャル認証の複雑さを隠すことで、APIの消費者をあなたのようにします。 oauthダウンストリームサイトのフロー中に、追加のoauth facebookを使用したフローをトリガーできます。

画像==単語* 1000のための画像:

enter image description here

これをoauth2-piggy-backと呼べますか?

段階的な流れ

  1. エンドユーザーがAPIを使用するサイトにアクセスする
  2. 承認またはサインアップ(oauth2)のためにエンドユーザーがサイトに送信されます
  3. エンドユーザーはソーシャル認証を選択し、Facebookのログインボタンをクリックします
  4. あなたのサイトはcookieを設定するか、facebookにstateを設定しますoauthはユーザーがどこから来たかを知るためです
  5. エンドユーザーはFacebookにリダイレクトされ、Facebookサイトでの接続を受け入れます
  6. エンドユーザーがFacebook認証プロセスを完了するためにサイトにリダイレクトされました
  7. データベースでユーザーを検索または作成します
  8. サーバー上に新しいセッションを作成します
  9. セッショントークンを使用して、ユーザーを元のサイトにリダイレクトします
14
James Sullivan

拡張可能にする方法

最初に、これらすべてのAPIがログインに同じメカニズムを使用していることに気付くはずです。それらはすべて、認証にOAuthを使用しています。これは、一般的なOAuthライブラリから開始して活用する必要があります。独自のライブラリを認証に使用しないでください。これらは他のプロバイダーでは使用できません。 OAuth2のコツをつかめば、プロバイダーを追加するのは非常に簡単です。

残念ながらそのうちの2つが必要です。これは、TwitterがまだOAuth2バンドワゴンにジャンプしていないためです。

OAuthでは、認証する側のインターフェースを作成する必要があります。トークンはサーバー間で交換されます。すべての通信を処理できる1つのエントリポイントを作成します。

トークンはアカウントとは別のテーブルに保存する必要があります。これは、トークンが複数のトークンと複数のリンクされたプロファイルになる可能性があるためです。一部のサービスは2つのトークンを提供し、そのうちの1つは更新トークンです。

次に、必要な他の機能をカプセル化するインターフェースを設計します。私はこれのために個別のRESTサービスを個人的にセットアップしました。このようにして、認証を他の場所に簡単に拡張できます。
一部のサービスはJSONを使用して通信し、他のサービスはXMLなどを使用します。フロントユーザーの場合、すべてを統合する必要があります。これはかなり骨の折れるプロセスですが、ここでいくつかの一般的な根拠を導き出すことが可能です。

ここでのもう1つの問題は、すべてのサービスが同じ機能を提供するわけではないことです。これは、サービスが指定したとおりの完全なAPIを提供できないことを意味します。ここでは、アプリケーションを正常にダウングレードできるようにする戦略が必要です。

これにより、新しいサードパーティプロバイダーを簡単に追加できます。

トークンの問題

トークンは時間に制限があるため、トークンがまだ使用可能かどうかを確認できるいくつかのcronジョブが必要です。それ以外の場合は削除する必要があります。このメカニズムでトークンを更新することもできます。

ユーザーがトークンを撤回する場合があります。この準備をしてください。

データストレージ

この設計の場合、必要なデータについて考える必要があります。これは、作成したばかりのインターフェースの一部です。このためのいくつかのテーブルを設計し、データが実際に取得可能かどうかを確認します。一部のサービスでは、大量のデータを取得できません。また、必要なデータが多いほど、プライバシーメッセージが重くなることも考慮する必要があります。だからあなたのニーズを控えめにしてください、さもなければユーザーはそれを使いません。

追加の検証のために、プロファイルをユーザーに個別のリンクされたテーブルに保存できます。これにより、誰かに関する多くの情報が提供されます。

また、地域の法律を確認してください。一部のデータについては、追加の注意が必要です。

最後のこと自分のサービスでアカウントを作成しないという過ちを犯さないでください。ユーザーがFacebookへの参加を禁止された場合、ユーザーは事実上、サービスにログインできなくなります。これは、作成したくない状況です。これは見過ごされがちです。

5
Edgar Klerks

私の2セント:私はこれまでこのようなことをしたことがなく、FB、Twitter、またはGoogleのログインメカニズムがどのように機能するかわかりませんが、質問を読むとすぐにいくつかの問題が頭に浮かびました。

  • 複数ログイン:あるFacebookアカウントでログインし、次のGoogleアカウントでログインするとどうなりますか?または同時に?これら2つのアカウントを一意の個別のアカウントとして扱うのですか、それとも2つを関連付けて、いずれかの方法でチケットにアクセスできるようにする方法を教えてください。
  • 外部識別子に依存: FacebookまたはTwitterがアカウント識別子の表示方法を変更すると、どうなりますか?たとえば、BazLoginがコード{4382-af56}を使用して一意のアカウントを表しているが、8では不十分だったため、今後12桁のアカウントになると判断した場合、{1234-4382-af56}に{0000-4382を伝えるにはどうすればよいですか。 -af56}?

セッションIDだけでなく、外部アカウントを内部アカウントに関連付けることを選択することで、これら2つの問題に対処できます。次に、外部ログインは、内部アカウントの作成への単なるゲートウェイになります。複数のログイン方法で認証すると、すでにログインしていることがわかります。外部の認証プロバイダーが依存するものを変更した場合、ユーザーに内部アカウントの名前とパスワードを提供してもらい、今後のログインのための新しい関連付け。

私があなたが考えていた問題に対処したかどうかはわかりませんが、具体的な懸念については何も触れていません。どちらにせよ、私の回答がお役に立てば幸いです。

1
idoby

私は間違いなくあなたがすでに理解しているように思えるソリューションを使用します:クライアントに面するWebサイトにサードパーティの認証を実装し、それらのサードパーティの認証トークンをWebサイトのユーザーアカウントに関連付け、最後にsetSessionID呼び出しをトリガーしますログインする。

Webサイトのアーキテクチャによっては、 EveryAuth または Passport のようなライブラリを使用すると非常に役立つ場合があります。

1
Rex