15

この質問は Stack で数回尋ねられましたが、実際の回答はありませんでした。とにかく私の状況を説明してみましょう。

Facebook OAuth2ログインを利用したアプリを使用しています。このログインは、先週まで問題なく機能していましたが、突然、私たちを悩ませています。

申し込みの流れ:

ステップ 1:ユーザーは、当社の Web サイトで Facebook ボタンでログインを押します

ステップ 2: Facebook のログイン/認証ページにリダイレクト

ステップ 3:アプリを承認すると、短期間の「コード」パラメーターを使用して、コールバックがアプリケーションに送信されます。

ステップ 4:この "code" パラメータは、" https://graph.facebook.com/oauth/access_token " URLを使用して 60 日間のアクセス トークンと交換されます。

ステップ 4 のエラー:

短命の「コード」をアクセス トークンと交換しようとすると、Facebook からこのエラーが発生します。

{"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100}}

観察:

  1. 新規にアプリをご利用になる方は、上記のエラーは発生しません。
  2. 戻ってきたユーザーの場合、この呼び出しは上記のエラーで失敗します。
  3. 私たちのアプリケーションは現在 9 か月以上稼働していますが、このエラーが発生したのは過去 7 ~ 10 日間だけです。それ以前に、何千人ものユーザーが問題なく使用してきました。

フォーラムからすでに得たもの:

これが私が読んだものの私の解釈です。不正確な場合があります。Facebook には、最初のログイン時に取得した 60 日間のコードの有効期限が切れるまで、アプリ開発者が一時的な 10 分間のコードを維持する必要がある奇妙なポリシーがあります。そのため、ユーザーのブラウザーでアクセス トークンを使用して Cookie を作成する必要があります。Cookie を作成するためにコードを変更している人も見られました。

本当に私を悩ませているのは何ですか?

  1. 提案された解決策は、作成した Cookie が常にユーザーのブラウザに存在することを前提としています。Cookie はいつでも消去される可能性があるため、これは間違った想定です。
  2. 開発に使用する別のアプリ ID/アプリ シークレット (つまり、localhost) があり、それは完全に機能します。ログインは正常に行われますが、問題があるのは製品マシンだけです。
  3. この問題は、アプリをリリースしてから 10 か月近く本番マシンでは発生していませんでしたが、突然発生しました。最悪なことに、この流れを壊す最近の変更の記録を取得できません。

編集:

プラットフォーム: Python、Google Appengine。Facebook SDK は一切使用せず、すべてのログイン URL に対して直接 HTTP 呼び出しを行います。失敗した呼び出し: https://graph.facebook.com/oauth/access_token - 最初の呼び出しが発生してから 20 秒以内に、appId、シークレット、およびコード (facebook から取得) を渡します。

私たちのコードが完全に間違っているわけではないことを示すのに十分な情報がここにあることを願っています. この問題に遭遇して解決した人からのヒント/ポインターは大歓迎です。それが Facebook のバグであり、Facebook の開発者が気付いた場合、私はさらに幸せになるでしょう。

4

2 に答える 2

4

Facebookに渡す各コールバックURLに追加されるランダムなGUIDを使用して、この問題を回避しました。Facebook が返すコードは、指定する必要がある redirect_uri パラメータを含むいくつかの部分で構成されているようです。この GUID トリックを使用すると、アプリは引き続き動作しますが、Facebook は別の URL であると認識し、新しいコードを生成します。

その GUID を一時セッションに保存すると、常に同じになります。これは、私が言いたいことの非常に簡略化されたバージョンです。私はC#を使用していますが、解決策は同じです:

oauth プロセスを開始する前に:

Session["facebook_buster"] = System.Guid.NewGuid().ToString();

次に、ログインを開始します。

var facebook = new FacebookClient();

var loginUrl = facebook.GetLoginUrl(new
{
    client_id = ...,
    redirect_uri = ..."/facebook/oauthcallback?buster=" + Session["facebook_buster"].ToString(),
    display = "popup",
    scope = "publish_stream,user_photos"
});

そして、コールバック メソッドで、そのコードを新しい access_token に交換したい場合:

var facebook = new FacebookClient();

dynamic result = facebook.Post("oauth/access_token", new
{
    client_id = ...,
    client_secret = ...,
    redirect_uri = ..."/facebook/oauthcallback?buster=" + Session["facebook_buster"].ToString(),
    code = Request["code"] // this is the returned code from the first method
});

2 番目の方法では、認証コードが成功するように同じセッション キーを使用していることに注意してください。

アクセス許可を取り消す/保存されたaccess_token(データベース内)を手動で変更する/保存されたaccess_tokenを完全に削除することにより、これを午前中ずっとテストしており、毎回機能します。

お役に立てれば!

于 2013-09-29T12:03:04.883 に答える
0

今日もしばらく悩みました。Facebook PHP クラスを使用しているかどうかはわかりません (あなたが書いたものから、そうではないようです)。自動的に、もう一度やろうとしていました。

于 2013-09-27T13:47:45.897 に答える