0

私は次の方法でアプリを認証しています:

// authorize app!
                $('#authApp').click(function(){
                    var oauth_url = 'https://www.facebook.com/dialog/oauth/';
                    oauth_url += '?client_id=#{app.id}';
                    oauth_url += '&redirect_uri=' + encodeURIComponent('https://www.facebook.com/pages/null/#{fbPageId()}/?sk=app_#{app.id}');
                    oauth_url += '&scope=user_likes,user_photos';
                    oauth_url += '&app_data=7B%27game%27%3A+%27key%27%7D';
                    oauth_url += '&state=sbSbsbSb';

ご覧のとおり、クエリ文字列の一部として「state」パラメータを設定しています。これで、ユーザーがアプリを承認すると、リダイレクトURLにリダイレクトされます。

ただし、stateパラメーターで渡されたデータはアプリに投稿されず、アプリのiframeクエリ文字列の一部でもありません。署名されたリクエストの一部としてそれを見つけることを期待していましたが、そうではありませんでした。これは、承認後にポストバックされた逆シリアル化された署名付きリクエストです

{ algorithm: 'HMAC-SHA256',
  expires: 1348927200,
  issued_at: 1348921162,
  oauth_token: 'AAA...',
  page: { id: '490...', liked: true, admin: false },
  user: { country: 'ec', locale: 'en_US', age: { min: 21 } },
  user_id: '1...' }

親ページのクエリ文字列に状態が含まれていることはわかります。アプリからそのパラメーターにアクセスする必要があります(iframe内で実行)。同一生成元ポリシーの制限のため、親ページのウィンドウの場所にアクセスすることはできないと思います。

ドキュメントを読み、オンラインで検索しました。アプリの認証全体でデータを永続化するには、stateパラメーターを使用する必要があります。ただし、アプリにリダイレクトされた後、その状態パラメーターを取得する方法についてはどこにも記載されていません。

これは、状態パラメータに関するFacebookドキュメントからのものです。

リクエストとコールバックの間でアプリケーションの状態を維持するために使用される一意の文字列。Facebookがユーザーをredirect_uriにリダイレクトすると、このパラメーターの値が応答に含まれます。クロスサイトリクエストフォージェリから保護するためにこれを使用する必要があります。

親のページクエリ文字列から状態データを取得することになっていますか?それとも私は何か間違ったことをしていますか?

*編集* 状態パラメーターにユーザーからユーザーへのリクエストIDを保存しています。たとえば、AはFacebookリクエストを介してアプリに参加するようにBを招待します。Bがアプリを承認したら、Aに報酬を与える必要があります。だから私はBがAの招待に続いてアプリに来たことを知る必要があります。したがって、requestIdを状態パラメーターに格納します。Bがアプリを承認すると、適切なアクションを実行できます。

*編集2(解決策)** redirect_uriがページタブのURLを指している場合、Facebookは状態パラメーターを送り返しません!CanvasURLにリダイレクトした場合にのみ返送されます!!!!!

4

2 に答える 2

1

親のページクエリ文字列から状態データを取得することになっていますか?

いいえ、キャンバス/ページタブアプリ内で認証する場合は除きます。このシナリオでアプリに渡される唯一のクエリ文字列パラメーターは、app_dataパラメーターのコンテンツです。

stateただし、このシナリオではパラメーターは必要ありませんsigned_request。アプリのシークレットで署名されているため、これを確認するだけで十分です。これは、あなたとFacebookだけが知っていることです。つまり、すでにそこにある「操作された」要求に対する十分な保護です。

https://developers.facebook.com/docs/authentication/canvas/respを参照してください。詳細については、 https://developers.facebook.com/docs/authentication/pagetab/を参照してください。(そして、彼らがstateパラメータについてまったく言及していないことを確認してください。)

編集:

ユーザーからユーザーへのリクエストIDをstateパラメーターに保存しています。たとえば、AはFacebookリクエストを介してアプリに参加するようにBを招待します。Bがアプリを承認したら、Aに報酬を与える必要があります。だから私はBがAの招待に続いてアプリに来たことを知る必要があります。したがって、requestIdを状態パラメーターに格納します。Bがアプリを承認すると、適切なアクションを実行できます。

これはパラメータの誤用stateです…完全に異なる何かを達成することになっています(ドキュメントが言うように、CSRF保護)。

これはシナリオでは機能する可能性がありapp_dataますが、この情報を送信するためにパラメーターを使用しないのはなぜですか?これは、キャンバス/ページタブアプリに情報を転送するための指定された方法です。

于 2012-09-29T15:43:09.093 に答える
1

あなたが参照したFacebookのドキュメントは少し紛らわしいです。状態パラメーターを使用して実行する必要があるのは、CSRFの犠牲にならないようにすることだけです。 Facebookのサーバー側認証フローは、PHPでのこの例を示しています。つまり、状態の値をセッションに保存してから、セッションの値がFacebookがリクエストで返すものと同じであることを確認する必要があります。PHPの例の重要な行は次のとおりです。

if($_SESSION['state'] && ($_SESSION['state'] === $_REQUEST['state'])) {
   // Continue with application logic here because state matches.
   // Otherwise, exit immediately because you're a victim of CSRF!

では、問題に戻りましょう。リダイレクトURLと取得した応答から、アプリがFacebookページタブにあることは明らかです。これを行う方法については、ページタブの認証フローを参照してください。手順2で状態パラメーターを使用していないこと、および状態パラメーターがページタブ認証フローで言及されていないことに注意してください。したがって、意図した用途以外の目的で状態パラメーターを使用したい場合でも、運が悪いことになります。

編集内容に基づいて、リクエストに関するドキュメントを確認することをお勧めします。リクエストをクリックしたユーザーは、ページタブではなく、キャンバスアプリにリダイレクトされることに注意してください。「キャンバスURLには、追加のGETパラメーターrequest_idsも含まれます。これは、ユーザーが操作しようとしている要求IDのコンマ区切りリスト区切りリストです。」したがって、これを自分で行おうとする必要はありません。

于 2012-09-29T15:54:03.667 に答える