4

トークンを持っていますが、「現在のユーザーに関する情報を照会するには、アクティブなアクセス トークンを使用する必要があります」というエラーが表示され続けます。どんな助けでも大歓迎です:)

    NSLog(@"TOKEN : %@",[[FBSession activeSession] accessToken]);

    NSString *picture = [NSString stringWithFormat:@"http://www.prowebdev.org/WooF/API/OpenGraph.php"];
    NSString *image = [NSString stringWithFormat:@"http://www.prowebdev.org/WooF/API/upload/356.jpg"];
    NSString *imageBool = [NSString stringWithFormat:@"true"];

    NSMutableDictionary *myDictionary = [NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:picture,image,imageBool, nil] forKeys:[NSArray arrayWithObjects:@"picture",@"image[0][url]",@"image[1][user_generated]", nil]];

    FBRequest *request  = [FBRequest requestWithGraphPath:@"me/mydogwoofs:posted" parameters:myDictionary HTTPMethod:@"POST"];
    FBRequestConnection *connection  = [[FBRequestConnection alloc] init];
    [connection addRequest:request completionHandler:
     ^(FBRequestConnection *connection, id result, NSError *error) {
         if (!error && result) {
             NSLog(@"Posted!");
         }else{
             NSLog(@"ERROR - %@", error);
         }
     }];
    [connection start];

ログ:

TOKEN : CAAD2QmzDZCHUBALgvURs9AmdO0ZCyj4Uws1pHbX9FYMbptaZAehn6318DEQPyiWpCDWs5O4DXoyAHiBajy37HAdkO648mOgpOZCxc73JhR9n0eO3KejeEkmgKTNSJti2GRmGuZCfhVm9X4cQhhk35ksfEdN8AGR7R6aP3dZBGFWQZDZD

Error: HTTP status code: 400
ERROR - Error Domain=com.facebook.sdk Code=5 "The operation couldn’t be completed. (com.facebook.sdk error 5.)" UserInfo=0x8b8abd0 {com.facebook.sdk:ParsedJSONResponseKey=<CFBasicHash 0x8b88fe0 [0x1bc3b48]>{type = mutable dict, count = 2,
entries =>
1 : <CFString 0x952a8 [0x1bc3b48]>{contents = "code"} = <CFNumber 0x8b885d0 [0x1bc3b48]>{value = +400, type = kCFNumberSInt32Type}
2 : <CFString 0x93eb8 [0x1bc3b48]>{contents = "body"} = <CFBasicHash 0x8b75ae0 [0x1bc3b48]>{type = mutable dict, count = 1,

entries =>
11 : <CFString 0x8b88f20 [0x1bc3b48]>{contents = "error"} = <CFBasicHash 0x8b888d0 [0x1bc3b48]>{type = mutable dict, count = 3,

entries =>
2 : <CFString 0x8b5f550 [0x1bc3b48]>{contents = "type"} = <CFString 0x8b88aa0 [0x1bc3b48]>{contents = "OAuthException"}
3 : <CFString 0x8b88a40 [0x1bc3b48]>{contents = "message"} = <CFString 0x8b889a0 [0x1bc3b48]>{contents = "An active access token must be used to query information about the current user."}
6 : <CFString 0x8b88e40 [0x1bc3b48]>{contents = "code"} = 2500
4

2 に答える 2

3

これが問題の原因であるかどうかは定かではありませんが、過去に Facebook SDK のアグレッシブ キャッシングで問題が発生しました。Facebook SDK は有効なログイン Facebook ユーザーを複数の場所で探すため、現在ログインしているユーザーをキャッシュすることで、後続の呼び出しでこの検索を省略します。ログインしている可能性のある Facebook ユーザーのいずれかが変更された場合、またはそのユーザーの認証が変更された場合、事態は少しおかしくなる可能性があります。

参考までに、Facebook SDK は、iOS 5 以降のシステム facebook アカウント、facebook 独自のネイティブ アプリへのアプリ間呼び出し、アプリで実行されている Web ビュー インスタンスのブラウザー Cookie を試行するか、サファリにバウンスして、 safari のブラウザー cookie...そのため、これらの異なるログイン アカウントのいずれかが変更された場合、またはそれらのアカウントのいずれかがアクセス許可を無効にしたり、パスワードを変更したりした場合 (たとえば)、SDK が積極的にキャッシュしすぎると、事態が混乱する可能性があります。これを回避するために、私は Facebook SDK セッションを開いた後、常にグラフ API に対してアクセス トークンをチェックしました。単純な「自分」のテストに合格した場合は、このアクセス トークンを有効なものとして受け入れて続行します。ただし、失敗した場合は、SDK にキャッシュされた値をフラッシュし、Facebook SDK に新しいセッションを強制的に再開させます。ログインしている可能性のあるすべての Facebook アカウントを調べて、アクティブなセッションを見つけます。これにより、新しいアプリケーション認証プロンプトが表示される場合と表示されない場合がありますが、アプリのアクセス トークンが機能するはずです。

サンプルコード

私が何をしているかを理解するのを助けるために、ここにいくつかの疑似コードがあります。(残念ながら、ここでコードの作業セットを簡単にコピーして貼り付けるにはあまりにも多くのものを抽象化してしまったので、いくつかの場所で空白を埋める必要があります:P)

メイン実行ループ

私の Facebook コードへのエントリ ポイントは、次の if ステートメントで始まります。この if ステートメントは、Facebook SDK の activeSession の現在の状態を調べ、アクセスを再プロンプトまたは検証します。

if (isSet(FBSession.activeSession) &&
    (FBSession.activeSession.isOpen || FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded))
{
    // Make sure the access_token is still authed and has the correct permissions first (can't trust what's cached by fb's sdk)
    [self checkAgainstGraphAPIOnVerified:^
    {
        // From the api the access_token looks ready, make sure fb sdk session is open as well
        if (FBSession.activeSession.isOpen)
        {
            // We're authenticated and session is open, good to go
            [self runIfFullAuth];
        }
        else if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded)
        {
            // We have a cached token (permissions all look good), we need to re-open the fb sdk session
            [FBSession.activeSession openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
                                    completionHandler:openSessionHandler];
        }
    }
    onInvalidated:^
    {
        // App isn't removed, but don't have required permissions anymore...
        if (FBSession.activeSession.isOpen)
        {
            // We have an open fb session, so just reprompt for permissions
            [self repromptForPermissions];
        }
        else if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded)
        {
            // We have a cached token, we need re-open the session first before reprompting
            [FBSession.activeSession openWithBehavior:FBSessionLoginBehaviorUseSystemAccountIfPresent
                                    completionHandler:openSessionHandler];
        }
    }
    onAppRemoved:^
    {
        // App is completely removed, so prompt for permissions
        [self openNewFBSession];
    }];
}
else
{
    // No valid access_token cached, prompt for permissions
    [self openNewFBSession];
}

呼び出される関数のほとんどは、非常に単純です。たとえばrunIfFullAuth、ユーザーが完全に認証され、検証済みのアクセス トークンが得られたら、必要なものを呼び出すだけです。 は、アクセス トークンを使用してcheckAgainstGraphAPIOnVerified:onInvalidated:onAppRemoved:への簡単な呼び出しを行う独自の関数です。返された json で ID が返された場合は、検証済みのアクセス トークンを取得しています。返された json に必要なアクセス許可がない場合は、アクセス トークンが無効になっています。グラフ API から何も返されない場合は、アプリが削除されたと見なします。graph.facebook.com/me?fields=permissionsFBSession.activeSession.accessTokenData.accessToken

openSessionHandler

openSessionHandlerオープンセッションをリクエストした後、Facebook SDK が私たちに何を返すかを理解する責任があります。ここでは、大まかに何をしているのかを示します。

void(^openSessionHandler)(FBSession *, FBSessionState, NSError *) = ^(FBSession *session, FBSessionState status, NSError *error) {
{
    if (error)
    {
        // Analyze the error
        if (error.fberrorShouldNotifyUser)
        {
            // Pop up alert for error
            if ([error.userInfo[FBErrorLoginFailedReason] isEqualToString:FBErrorLoginFailedReasonSystemDisallowedWithoutErrorValue])
            {
                // App disabled in facebook settings... pop up alert
            }
            else if ...
            else if ...
            else if ...
            else
            {
                // Show pop up alert with error.fberrorUserMessage
            }
            [self runIfNoAuth];
        }
        else if (error.fberrorCategory == FBErrorCategoryUserCancelled)
        {
            // User canceled
            [self runIfNoAuth];
        }
        else if (error.fberrorCategory == FBErrorCategoryAuthenticationReopenSession)
        {
            [self repromptForPermissions];
        }
        else
        {
            // Something else happened... probably network issue with Facebook servers
            [self runIfNoAuth];
        }
    }
    else
    {
        switch (status)
        {
            case FBSessionStateOpen:
            {
                [self checkAgainstGraphAPIOnVerified:^
                {
                    [self runIfFullAuth];
                }
                onInvalidated:^
                {
                    [self repromptForPermissions];
                }
                onAppRemoved:^
                {
                    // If we're here, then we're in a fucked up state.  We just prompted the user for auth, and
                    // the facebook sdk thinks we have an open session, but an api call proves that we're not actually
                    // authed.  A few possible ways to get to this point:
                    // 1) The multi-screen auth inside facebook's ios app is used (ie. not system facebook account) and
                    //      the user grants general permissions, but before granting posting permission (second page),
                    //      goes to facebook.com and removes application permissions
                    // 2) The user's facebook account password has changed, and the phone's system facebook account
                    //      hasn't been updated with the new password

                    // Pop up alert... tell user to check their Facebook settings
                    [self runIfNoAuth];
                }];
                break;
            }

            case FBSessionStateClosed:
            case FBSessionStateClosedLoginFailed:
            {
                [self clearCachedFBInfo];

                // If you want, you can choose to reprompt the user for permissions here... but it would most likely result in an endless loop where the only way out is for the user to log in :)
                [self runIfNoAuth];
                break;
            }

            default:
                break;
        }
    }
};

clearCachedFBInfo

最後に、キャッシュされたセッション情報を Facebook SDK からクリアする方法を次に示します。

[FBSession.activeSession closeAndClearTokenInformation];
[FBSession.activeSession close];
[FBSession setActiveSession:nil];

正直に言うと、 の 2 回目の呼び出しcloseが冗長かどうかはわかりませんが、これが私がいつも行ってきた方法です.... ハハハ

ああ、関数の先頭でopenNewFBSession、Facebook SDK を強制的に最初からやり直して新しい Facebook セッションを検索する必要があるときに呼び出すclearCachedFBInfo関数を呼び出します。これにより、SDK にキャッシュされた Facebook 情報がないことが保証され、新しいセッションが開かれます。

最後に、これがあなたが見ている問題を引き起こしているかどうかはまだわかりませんが、過去に有効ではないように見える有効なアクセストークンで非常に厄介な問題を経験したことは間違いありません。これが私が修正した方法です私の問題。幸運を!また、ご不明な点がございましたら、喜んでお答えいたします。

于 2013-06-13T08:51:39.673 に答える