保護されたWebサービスにもアクセスするiOSアプリでのFacebook認証の設計


402

目標: Facebookを使用して、実行中の保護されたWebサービスへのアクセスを必要とするiOSアプリケーションへの認証をユーザーに許可します。

前提条件: サインインにFacebookを使用しないことを選択したユーザー向けに、ネイティブ認証(および登録)システムが用意されています。

詳細:

  • ユーザーがシステム用に個別のアカウント/資格情報を作成せずにFacebookにサインインするオプションを提供したいとします。
  • 私たちは独自のネイティブ認証メカニズム(ユーザー名とパスワード)をサポートしているため、独自のユーザーIDを持ち、最初の資格情報の検証後のやり取りに使用される認証トークンを発行します。

Facebookの開発者向けドキュメントに、これに関するベストプラクティスがないことに驚いています。既存のドキュメントはすべて、FB認証をWebサイトに構築すること、または認証を必要とするサービスのないスタンドアロンのモバイルアプリを想定しています。

これがどのように設計されるかについての最初の考えは次のとおりですが、それが正しいかどうかの検証が必要です。

  1. クライアントがFacebook iOSログインをポップします
  2. UIユーザーはFacebook認証情報でサインインし、アクセストークンを取得します
  3. iOSアプリがアクセストークンをサーバーに渡す
  4. サーバーは、アクセストークンを使用してFBグラフAPIと通信し、(a)トークンを検証し、(b)そのアクセストークンのFBユーザーIDを取得します。

    たとえば、サーバーはhttps://graph.facebook.com/me/?access_token=XYZを呼び出し、JSONオブジェクトでプロファイル情報を返します。

  5. 有効であると想定すると、サーバーはJSONオブジェクトからユーザーIDを抽出し、ユーザーがすでにアカウントを持っているかどうかを確認します。その場合は、そのセッションで使用するためにクライアントに独自の認証チケットを発行します。ユーザーがアカウントを持っていない場合は、FacebookユーザーIDで新しいアカウントを作成し、独自の一意のユーザーIDを割り当てて、認証チケットを発行します。

  6. 次に、クライアントは、認証を必要とする後続の対話で認証チケットを返します。

これは私にとっては正しいアプローチのようですが、めちゃくちゃ基本的なものを見逃していて、間違った(複雑な)パスをたどっているかどうかはわかりません。


1
これはどのように解決されましたか?私もアクセストークンを渡して、サーバーでユーザーをスピンアップすることを検討しています。学術的なようですが、尋ねています。
Chris Van Buskirk

これは、レールと工夫を使用して、私の実装だった: stackoverflow.com/questions/7232490/...
マット

FB APIへの2つの呼び出し(iOSデバイスから1つとサーバーから1つ)を実行する代わりに、auth_hash全体を渡さないのはなぜですか?
bsiddiqui 2013年

1
別のデバイスからログインしたい場合(つまり、認証チケットがない場合)また、新しい認証チケットを受け取っただけで、誰かが途中でFacebookのIDやトークンをハイジャックして、自分のデバイスでそれを使用できないようにするにはどうすればよいでしょうか。
Amitloaf 2014

好奇心から、ステップ5で独自の認証チケットを発行する理由を教えてください。後続のすべてのサーバー呼び出しにFacebookアクセストークンを使用できませんか?最初の呼び出しだけでなく、すべてのアプリでサーバーからFacebook APIへの呼び出しが必要になることは理解しています。
アンデルス2014年

回答:


80

私はこれを自分で処理しました、そしてここが私を噛んだ部分です:

あなたのステップ5では...ユーザーはFacebook IDとは完全に別のアカウントに登録することができますよね?その後、もう一度Facebookでログインします。そして、2番目のアカウントを作成し、最初のアカウントを失いました。

WebサービスにログインしてからFacebookにログインし、Facebook IDとローカルアカウント間の関連付けを取得する方法が必要です。

それとは別に、あなたの計画は堅実に聞こえます。

アップデート:Facebookは、このようなAシナリオまとめたドキュメントを追加しましたHEREを


7
ええ、私はそれを考慮しました、そしてあなたはその場にいます。同じメールアドレスの場合はアカウントを統合する予定です。そうでない場合は、別の方法でアカウントを統合します。
TMC

リクエストを行うためにサーバー側で使用しているサーバーライブラリはどれですか。
TimLeung

7
@TimLeung-私の理解では、アクセストークンにはアプリIDが埋め込まれており、アプリIDなしでアクセストークンを作成することはできません。
Dan Ray

1
@TimLeunge:ユーザーのアクセストークンを使用したリクエストにGraph APIを使用しています。
TMC

29

Facebookで述べられているように、httpsを使用して認証トークンをサーバーに送信します

アクセストークンの共有

データポリシーでは、アプリのアクセストークンを他のアプリと共有することを明示的に禁止しています。ただし、HTTPSを使用して転送が行われる限り、デベロッパーは同じアプリのネイティブ実装とサーバー実装間で(つまり、同じアプリIDを使用して)トークンを共有できます。


16

この戦略で見られる1つの問題は、別のFacebookアプリ用に取得したアクセストークンを誰かがあなたに提供できることです。私の知る限り、アクセストークンがアプリケーション用であることを確認する方法はないので、そのまま使用します。

とはいえ、それほど有害な音にはならない。一般に、ユーザー/アプリはアクセストークンを共有するのではなく、保護しようとします。

この悪用の可能性の1つは、誰かが独自のサイトまたはモバイルアプリを作成し、ユーザーのアクセストークンを取得して、APIを使用してそれらを認証しようとすることです。これが成功した場合(ユーザーがサイトにFacebookアカウントを持っている場合)、悪意のあるサイトはAPIを使用してユーザーになりすますことができます。

少し長いショットですが、うまくいくと思います。

編集:結局アクセストークンを検証する方法があるようです。ユーザーアクセストークンからアプリケーションIDを取得する(またはトークンのソースアプリケーションを確認する)質問について@Daanielの回答を参照してください。


送信appsecret_proofすることでこれを防ぐ必要があります(ここを参照)
Tony

@Tony appsecret_proofはここでどのように役立つか説明できますか?私が理解している限り、それはサーバーが秘密鍵を知っていることをFacebookに証明するのに役立ちます。ただし、ivantはトークンを取得してAPIに送信する悪意のあるアプリを参照していました。サーバーはアプリIDを確認できますが、アプリIDは悪意のあるアプリによって簡単になりすまされる可能性があります。それで...これをどのように軽減しますか?
YSK 2017

3
https://graph.facebook.com/app/?access_token=[user_access_token]アプリIDを返すトークンがアプリ用に生成されたことを確認し、アプリIDを比較することができます
Nader Alexan

4

あなたのソリューションは完全に機能します。

たぶん代替手段:クライアントで最初のソーシャルサービスリクエストから電子メールを取得してWebサービスに送信するだけではどうですか?Webサービスはメールだけを保存することができ、おそらくsocial_providerも保存できます。メールがどこから来たのかをWebサービスで検証できないことを理解していますが、Webサービスとクライアントの間に信頼関係はありませんか?ある場合は、適切な場所からのメールに依存しているようです。誰か私に欠けている明らかなことを教えてください


3
クライアントがサーバーと通信している方法を簡単に見つけることができました。その後、私はヒットするまでメールを投げることができました。常に何らかの検証が必要です
Chris

5
高い信頼とクライアント?同じ文には絶対に入れないでください。もちろん前の文を除いて。
EralpB 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.