認証にFacebookを使用するWebサイト用のRESTAPI


86

ログインしてサイトで自分自身を認証する唯一の方法がFacebookを使用するWebサイトがあります(これは私の選択ではありませんでした)。Facebookに初めてログインすると、アカウントが自動的に作成されます。

ここで、私たちのサイト用のiPhoneアプリケーションと、他の人が私たちのサービスを使用するためのパブリックAPIを作成したいと考えています。

この質問は、アプリ/ APIから当社のWebサイトで認証する方法に関するもので、2つの部分に分かれています。

  1. APIからFacebookOAuthのみを認証方法として使用するWebサイトへのREST認証を処理する正しい方法は何ですか?

    私はRESTAPIの標準的な認証方法について多くのことを読み、調査しました。ユーザーの資格情報がないため、HTTPS経由の基本認証などの方法を使用することはできません。このようなものは、APIを使用してアプリケーションを認証するためだけのもののようです。

    現在、私が考える最善の方法は、APIで/ authorizeエンドポイントに到達し、Facebook OAuthにリダイレクトしてから、サイトにリダイレクトし、APIのユーザーが後続の認証に使用できる「トークン」を提供することです。リクエスト。

  2. 私たちが作成する公式アプリケーションの場合、必ずしも同じ方法でパブリックAPIを使用する必要はありません。それでは、当社のWebサイトに話しかけてユーザーを認証するための最良の方法は何でしょうか?

API(公開)キーと秘密(プライベート)キーを使用して、APIを使用しているサードパーティアプリケーションを認証する方法を理解しています(私は思います)。ただし、アプリを使用しているユーザーの認証に関しては、ユーザーを認証する唯一の方法がFacebookである場合、その方法についてかなり混乱しています。

非常に明白なものが欠けている、またはパブリックREST APIがどのように機能するかを完全に理解していないように感じるので、アドバイスやヘルプをいただければ幸いです。


私はstackoverflow.com/questions/30230482/で同様の質問があります

回答:


99

更新:以下を参照

私もこの質問について一生懸命考えてきました。まだ完全にはわかりませんが、これが私が考えているルートです。Facebook接続でユーザーのみの認証を行うRESTAPIを作成しています。

クライアントの場合:

  1. Facebook APIを使用してログインし、OAUTH2コードを取得します。
  2. このコードをアクセストークンと交換します。
  3. カスタムAPIを呼び出すたびに、FacebookのユーザーIDとアクセストークンを含めます。

APIの場合(ユーザー認証を必要とするすべてのメソッドの場合):

  1. 上記のアクセストークンを使用して、/ meFacebookグラフにリクエストを送信します。
  2. 返されたFacebookユーザーIDが、上記からAPIに渡されたユーザーIDと一致することを確認します。
  3. アクセストークンの有効期限が切れている場合は、追加の通信が必要です。

私はまだこれをテストしていません。どのように聞こえますか?

---更新:質問に答えるために2014年7月27日---

私はログイン時に一度だけ上記の交換を使用します。ログインしているユーザーを特定したら、独自のアクセストークンを作成し、そのトークンがその時点から使用されます。したがって、新しいフローは次のようになります...

クライアントの場合:

  1. Facebook APIを使用してログインし、OAUTH2コードを取得します。
  2. このコードをアクセストークンと交換します。
  3. パラメータとしてFacebookトークンを含め APIからアクセストークンをリクエストします

APIについて

  1. アクセストークンリクエストを受信します。
  2. Facebookアクセストークンを使用して/ meFacebookグラフにリクエストを送信します
  3. Facebookユーザーが存在し、データベース内のユーザーと一致することを確認します
  4. 独自のアクセストークンを作成して保存し、クライアントに返して、この時点から使用できるようにします

ねえ、それはちょっと遅い返事です、しかしあなたの解決策は私が私の最初の答えで持っていた問題を修正するようです。もちろん、(id、token)ペアをクリアテキストでネットワークに送信しないようにするには、HTTPSを使用する必要があります。しかし、それはうまくいくはずです!
オリビエランス

サーバーで/ meを呼び出して、モバイルクライアントで使用される独自のアクセストークンを生成するのは良いことだと思います。
Der_Meister 2014年

FBシークレットをモバイルアプリに保存するのは悪い習慣だと思いました。Facebookは、サーバーにのみ保存するようアドバイスしています。developers.facebook.com/docs/opengraph/using-actions/...
Der_Meister

user_idとaccess_tokenを毎回APIサーバーに送信する場合(post / get paramsとして)。誰かが接続を傍受できる場合、セキュリティホールが作成されますか?
Nathan Do

@NathanDoクライアントとAPIサーバー間でHTTPSを使用します。誰かが接続を傍受しても、問題にはなりません(ハートブリードタイプの脆弱性は別として)。
dcr 2014年

15

これは、JWT(JSON Web Tokens)を使用した私の実装であり、基本的にChrisの更新された回答に似ています。Facebook JSSDKとJWTを使用しました。

これが私の実装です。

  1. クライアント: Facebook JS SDKを使用してログインし、アクセストークンを取得します。

  2. クライアント:/verify-access-tokenエンドポイントを呼び出して、APIからJWTをリクエストします。

  3. MyAPI:アクセストークンを受け取り/me、FacebookAPIのエンドポイントを呼び出して確認します。

  4. MyAPI:アクセストークンが有効な場合、データベースからユーザーを検索し、存在する場合はユーザーにログインします。ペイロードとして必須フィールドを使用してJWTを作成し、有効期限を設定し、秘密鍵で署名して、クライアントに送り返します。

  5. クライアント: JWTをローカルストレージに保存します。

  6. クライアント:次のAPI呼び出しのリクエストとともに、トークン(ステップ5のJWT)を送信します。

  7. MyAPI:秘密鍵を使用してトークンを検証します。トークンが有効な場合は、トークンを新しいものと交換し、API応答とともにクライアントに送り返します。(その後、トークンの検証を求める外部API呼び出しはありません)[トークンが無効/期限切れの場合、クライアントに再度認証して1から繰り返すように要求します]

  8. クライアント保存されているトークンを新しいトークンに置き換え、次のAPI呼び出しに使用します。トークンの有効期限が切れると、トークンは期限切れになり、APIへのアクセスが取り消されます。

すべてのトークンは1回使用されます。

セキュリティとJWTに関する回答をもっと読む

JWTの安全性

JWTをデコードできる場合、どのように安全ですか?

ユーザー識別および認証トークンとしてのJSONWebトークン(JWT)


3
#3はむしろそうあるべきだと思う/debug_tokenので、トークンが実際にアプリケーション用であることを確認できます。
ペッペLG

2
access_tokenクライアントでリクエストしないでください。「コードワークフロー」を使用します。渡しcodeMyAPIに交換するのFacebookへの別のラウンドトリップを作るcodeaccess_token。これはここでより完全に説明されています:developers.facebook.com/docs/facebook-login/security
omikron 2016

5

私は同じ質問に答えようとしていて、最近たくさんの読書をしています...

私には「その」答えはありませんが、物事は私にとって少し明確になっています。あなたが言及た記事のコメントを読んだことがありますかか?私はそれらが本当に面白くて役に立ったと思いました。

その結果、そして最初の記事が書かれてから物事がどのように進化したかに照らして、これが私がやろうと思うことです:

  • どこでもHTTPS—これにより、HMAC、署名、ナンスなどを忘れることができます。

  • OAuth2を使用する:

    • 認証要求が自分のアプリ/ Webサイトから送信される場合は、前述の記事への返信で説明されているこの「トリック」(またはそのバリエーション)を使用してください

    • 私の場合、2種類のユーザーがいます。従来のログイン/パスワード資格情報を持つユーザーとFacebookConnectにサインアップしたユーザーです。
      そこで、「Facebookでログイン」ボタン付きの通常のログインフォームを提供します。ユーザーが「クラシック」資格情報を使用してログインする場合は、これらをOAuth2エンドポイントに送信しますgrant_type=password
      彼がFacebook経由でログインすることを選択した場合、それは2段階のプロセスになると思います。

      • まず、Facebook iOSSDKを使用してFBSessionを開きます
      • それが完了し、アプリが制御を取り戻されたら、そのユーザーのFacebookIDを取得する方法があるはずです。このIDだけをOAuth2エンドポイントに送信し、サーバーが「FBユーザーIDを使用している」と理解する拡張機能を付与します。

私はまだこれらすべてのことについて徹底的に研究しているので、それは完璧な答えではないかもしれないことに注意してください...多分正しいものでさえないかもしれません!しかし、それは良い出発点になると思います。Facebook認証に「拡張許可」を使用するという考えは、物事を適切に行うためにそれを登録する必要があるかもしれませんか?私はあまりよく分からない。

とにかく、私はあなたを少しでも助けることができたと思います、そして少なくともそれがこの問題の最良の解決策を見つけるために議論を始めることができることを願っています:)

更新
Facebookログインは、コメントで指摘されているように解決策ではありません。誰でも任意のユーザーIDを送信し、APIでこのユーザーとしてログインできます。

このようにするのはどうですか?

  • 「Facebookログイン」ボタンでログインフォームを表示する
  • このログイン方法を選択した場合は、Facebook SDKのように動作します。認証サーバーからWebページを開くと、Facebookログインが開始されます。
  • ユーザーがログインすると、FacebookはリダイレクトURLを使用して確認します。そのURLが認証サーバーの別のエンドポイントを指すようにします(おそらく、呼び出しがアプリから来たことを示す追加のパラメーターを使用しますか?)
  • 認証エンドポイントに到達すると、認証はユーザーを安全に識別し、そのFBユーザーID / FBセッションを保持し、Facebook SDKと同様に、カスタムURLスキームを使用してアプリにアクセストークンを返すことができます。

良く見えますか?


1
お返事ありがとうございます!私はあなたが言ったことのほとんどについて考えていましたが、FB iOS SDKを使用してFacebookユーザーIDを送信する際の主な懸念は、APIエンドポイントに必要なIDを送信して主張するのは簡単ではないということでした別のユーザー?これは私が通常立ち往生終わるところ..です
アダム

確かに!それは私がそれについて考えるのは愚かでした...それで、解決策はどういうわけかあなた自身の認証サーバーを通過しなければなりません...
Olivier Lance

私は別の解決策のアイデアで私の答えを更新しました...しかし、あなたが元の質問でそれについて言及したことに気づきました!私は...現時点で何かを見ることができない
オリヴィエ・ランス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.