web-dev-qa-db-ja.com

Facebook OAuthログイン-access_tokenAPIが「この認証コードが使用されました」を返します

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

FacebookOAuth2ログインを使用するアプリケーションを使用します。このログインは先週まで正常に機能していましたが、突然、問題が発生しました。

アプリケーションフロー:

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

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

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

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

ステップ4のエラー:

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

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

観察:

  1. アプリケーションに新しく来ているユーザーの場合、上記のエラーは発生しません。
  2. リピーターの場合、この呼び出しは上記のエラーで失敗します。
  3. 私たちのアプリケーションは現在9か月以上稼働しており、このエラーは過去7〜10日間でのみ発生しています。それ以前は、何千人ものユーザーがこれをうまく使用してきました。

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

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

本当に気になっていることは何ですか?

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

編集:

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

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

15
Srivatsan

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を完全に削除することで、これを午前中テストしてきました。毎回機能します。

お役に立てれば!

4
royse41

今日もしばらくこれに苦労しました。 Facebook PHPクラスを使用しているかどうかはわかりません(あなたが書いたものから、あなたはそうではないようです)、しかし、それはとにかくポインタである可能性があります-問題はFacebook = PHPライブラリはコードからトークンを自動的に取得しているようで、もう一度やり直そうとしました。

0
fromin