14

IIS 7.5 および VS 2010 で実行される WCF サービスがあります。このサービスには、 Facebookとの間で GET および POST を実行するために、 Facebook C# SDK (バージョン 4.1、最新ではない) を内部的に使用するメソッドがいくつかあります。Facebook はまもなくを削除するのでoffline_access、アクセス トークンの有効期限が切れた状況に対処する必要があります。

Graph API を使用して Facebook 情報を取得するために (コードを取得するため、およびアクセス トークンを取得するためのコードを取得した後に) 認証が実行される方法を理解しました (ここに示されているように)。

2 つの質問があります。

  • サービス メソッドが呼び出され、DB から適切なユーザーのトークンを取得するときに、アクセス トークンの有効期限が切れているかどうかを知る方法はありますか? Facebook API 呼び出しが実行され、アクセス トークンの有効期限が切れると、次の例外がスローされること
    読みOAuthExceptionました: . しかし、有効期限を検出するより良い方法はありますか? したくない
    1. Facebook API を呼び出す
    2. 例外を処理する
    3. アクセストークンを更新して最後に
    4. 新しいアクセス トークンを使用して最初の呼び出しを繰り返します。
  • ユーザーのアクセストークンを透過的に更新(DBにも格納)し、引き続きサービスメソッドを処理することはできますか? このリソースでは重要な (「アクセス トークンの更新」) 部分が欠落しています ([todo] として宣言されています)。

サービスメソッドの実装で、次のスキームを実現したいと思います。

sc = SocialNetworkAccountDao.GetByUser(user)

isExpired = call method to check if the sc.token is expired.

if (isExpired)

{

  newToken = call method for getting new access token

  sc.token = newToken;

  SocialNetworkAccount.Update(sc);

}

Facebook = new Facebook (sc.token)

Facebook.Post( ..... )

--

ダイアログとの通信処理QAuthは非同期(リダイレクトを行います)で、アクセストークンを取得するためのアクセストークンurlとの通信は同期的に行われます。

最後の質問:

  • 後で新しいアクセス トークンを使用して続行するために、Facebook のリクエスト/コールバックから取得した新しいアクセス トークンをサービス メソッドが待機する方法はありますか?
4

3 に答える 3

14

C# SDK についてはわかりませんが、すべての facebook SDK は基本的に、グラフのさまざまな URL への http 要求の単なるラッパーです。

サーバー側の認証フローを使用する場合、有効期限が長いトークン (約 60 日) を取得する必要があり、有効期限が切れると、ユーザーを再認証する必要があり、トークンを延長する方法はありません。 .

クライアント側の認証は有効期間の短いトークン (約 2 時間) を返しますが、「offline_token」を置き換えるために提供された新しいエンドポイントfacebook を使用できます。これは、まだ有効なアクセス トークンでのみ使用できます。

また、有効期限のないアプリケーション トークンでない限り、アクセス トークンを取得すると必ず「有効期限」が表示されます。

どちらの場合でも、有効期間の長いトークンを取得すると、それをデータベースに保存してサーバー側で使用できますが、トークンはさまざまな理由で無効になる可能性があることに注意してください。

また、無効なアクセス トークンと期限切れのアクセス トークンの処理に関する公式ドキュメントを使用することもできます。C# SDK がうまく機能しない場合は、必要に応じて自分で実装するだけで十分です。

于 2012-05-04T15:57:05.273 に答える
12

c#sdk を最新バージョンに更新する必要があります。時間の経過とともに多くの問題が修正されます。

これは、renew 呼び出し自体を処理するコードです (c#sdk バージョン6.0.16
ですが、これは以前のバージョンでも機能するはずです)。

    /// <summary>
    /// Renews the token.. (offline deprecation)
    /// </summary>
    /// <param name="existingToken">The token to renew</param>
    /// <returns>A new token (or the same as existing)</returns>
    public static string RenewToken(string existingToken)
    {
        var fb = new FacebookClient();
        dynamic result = fb.Get("oauth/access_token", 
                                new {
                                    client_id         = FACEBOOK_APP_ID,
                                    client_secret     = FACEBOOK_APP_SECRET,
                                    grant_type        = "fb_exchange_token",
                                    fb_exchange_token = existingToken
                                });

        return result.access_token;            
    }

Facebook によると、新しいトークンは同じ (ただし、有効期限が延長されている) または完全に新しいものである可能性があるため、必要に応じてロジックでそれを処理する必要があります。

Facebook によると、1 日 1 回まで更新を呼び出す必要があります。( https://developers.facebook.com/roadmap/offline-access-removal/ )

前回の「Facebook 更新」がいつ行われたかのタイムスタンプを保持し、その時間が 24 時間以上前で、ユーザーがアプリケーションにアクセスしている場合は、バックグラウンドでトークンを更新します。(他のデータ、名前、電子メール、その他必要なものも更新します)

どうやら、1 日 1 回までではなく、トークンごとに 1 回呼び出しているようです。

Facebook では、長期間有効なトークンを更新することはできません。オフライン アクセスの削除ページの「シナリオ 4:」を参照してください。

明確にするために、短命のトークンはクライアントから取得され、長寿命のトークンはサーバー側から取得されます。

つまり、ユーザーがアプリにアクセスすると、クライアントの SDK を使用して新しい短命のトークンを取得し、それをサーバーに送信し、それをサーバーで拡張して長命にし、それを保存します。そこから60日。

有効期限の処理
現在の使用法では、有効期限を追跡する必要はありませんでした。これは、すべてのアクセスが有効期限をチェックするクライアントから開始されるためresult.access_tokenですresult.expires。新しく取得したトークン (5 ミル => 60 日近くあるはずです))。

いずれにせよ、認証プロセスを再度呼び出さずにトークンから有効期限を取得する方法があるかどうかはわかりません。Facebook デバッガーがこれを返すことは知っていますが、それは実際には役に立ちません..

無効なトークンの更新
これは機能しません。期限切れ/無効なトークンを更新しようとすると、ここで説明されているエラーが表示されます。
有効期限が切れる前に renew を呼び出すことを忘れないでください。また、有効期限が切れた (またはその他の種類の無効なもの) で renew を呼び出すと、エラーが発生し、それを処理する必要があることに注意してください (貼り付けたコードの外で処理します)。

于 2012-05-08T16:37:49.573 に答える
5

有効期限が切れるまでの時間

簡単な答え:有効期限が切れるまでの秒数は取得しますが、c#APIはそれを公開していないようです。

このFacebookのドキュメントによると、トークンを取得したときに、パラメーターがパラメーターとして期限切れになるまでの秒数を取得します。ドキュメントには、応答形式が次のようにリストされています。

access_token=USER_ACESS_TOKEN&expires=NUMBER_OF_SECONDS_UNTIL_TOKEN_EXPIRES 

これは、応答に有効期限を含める必要があるというOuath2のRFCドラフトによって裏付けられています。

残念ながら、ここに次のように記載されているC#SDKドキュメントとは直接矛盾しています。

Facebookにリクエストを送信せずに、アクセストークンの有効期限が切れているかどうかを判断する方法はありません。このため、Facebookにリクエストを送信するときは、アクセストークンの有効期限が切れている可能性があることを常に想定する必要があります。

本当じゃない。c#SDKソースを見ると、sdkがOAuth応答用に作成するオブジェクトには、(残念ながらプライベート変数として)次のコードが明示的に含まれています。

    /// <summary>
    /// Date and Time when the access token expires.
    /// </summary>
    private readonly DateTime _expires;

したがって、データはありますが、何らかの理由で公開されていません(少なくとも、私はこれ以上調べませんでした)。ライブラリをさらに掘り下げてどこかに公開されているかどうかを確認するか、githubでフォークしてパッチを適用するか(1行の変更だと思います)、リフレクションを使用して独自のコードでプライベート変数を読み取ります。

サービスメソッドの処理とトークンの更新を継続します

簡単な答え:たぶん。トークンの有効期限が切れていることを知っていれば、リクエストの前に明らかに新しいトークンを取得できます。

そうしないと、ちょっとできますが、失敗したリクエストを処理する必要があります。理論的には、これは例外を処理する必要があるという意味ではありません。httpステータスコード(おそらく400では禁止されている403の1つです)を見てください。ただし、C#のwebrequestメソッドは、例外を発生させるイベントとして200以外のステータスcをインターペットします。APIはこのメカニズムを使用して呼び出しを行うため、失敗した場合にのみ例外が発生します。

サービスメソッドが、から取得した新しいアクセストークンを待機する方法はありますか?

確かに、例外を処理した後。

これが発生すると、非同期で、新しい認証トークンを取得します。したがって、例外をキャッチした後、しばらく待って、そのユーザーの新しいトークンを取得するかどうかを確認し、取得する場合は再試行できます。待ってチェックし続けるなら。最大再試行回数と最大待機時間があることを確認してください。データベースをプルして変更をチェックするのは少し非効率的であるため、変更をチェックする時間間隔を慎重に選択し、指数バックオフにする可能性があります。

もう1つの、より効率的(単一サーバーの場合)ですが、複雑な方法は、認証トークンを使用してコールバックを取得するシステムにイベントを発生させ、再試行ロジックにそれらのイベントをリッスンさせることです。

トークンの有効期限が切れたためにコードで例外が発生した場合、catchブロックで、リクエストをやり直し、それをイベントリスナーとして認証イベントに追加する関数を作成します。イベントが、イベントを要求するユーザーの新しい認証トークンに対するものであることを関数に確認させ、そうであれば、要求を行います。繰り返しになりますが、最大再試行回数を忘れないでください。

async / awaitなどを実際に使用して、新しいトークンの要求が完了するのを待つことはできません。問題は、APIトークンを更新することは、応答を待つことを要求することではなく、実際に何かをトリガーして、最終的に別のget要求が行われるようにすることです
FacebookAPIリクエスト 。ただし、上の図はユーザーが最初にログインしたときのものですが、同じです。シーケンスは大まかに失敗した呼び出しで発生しますが、リダイレクトから始まります。

于 2012-05-03T20:31:17.680 に答える