web-dev-qa-db-ja.com

Facebook SDK 3.1-アクセストークンの検証エラー

アプリを新しいFacebook SDK 3.1(iOS6認証のサポート付き)に移行しようとしています。

正常に機能していたので、FB Webサイトの承認済みアプリのリストからアプリを削除して、iOSが再度許可を要求することをテストすることにしました。

[FBRequest requestForMe]への最初の呼び出しにより、このエラーが発生します。

応答:

{
  "error": {
    "message": "Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.",
    "type":"OAuthException",
    "code":190,
    "error_subcode":460
  }
}

いくつかの詳細:

私は次のようにセッションを開こうとしています:

   [FBSession openActiveSessionWithReadPermissions:nil
                                       allowLoginUI:YES
                                  completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {

                                           switch (state) {
                                               case FBSessionStateOpen:
                                                   [self presentPostOptions];
                                                   break;

                                               case FBSessionStateClosed:
                                               case FBSessionStateClosedLoginFailed:
                                                   [FBSession.activeSession closeAndClearTokenInformation];
                                                   break;

                                               default:
                                                   break;
                                           }

その後、状態FBSessionStateOpenでコールバックされます(この時点でiOSは要求ダイアログを表示していませんが、それは予想されることですか?) Facebookはこれをログに記録します。

2012-09-26 13:43:43.768 MyApp[2177:907] FBSDKLog: FBSession INVALID transition from FBSessionStateCreated to FBSessionStateClosed
2012-09-26 13:43:43.769 MyApp[2177:907] FBSDKLog: FBSession transition from FBSessionStateCreated to FBSessionStateCreatedOpening 
2012-09-26 13:43:43.837 MyApp[2177:907] FBSDKLog: FBSession transition from FBSessionStateCreatedOpening to FBSessionStateOpen 

セッションが開いたら、presentPostOptionsでこれを行います。

- (void)presentPostOptions
{    
    [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
        if (!error) {
            self.usersName = user.name;
            self.usersID = user.id;

            [self getPages];
        }
        else
        {
            [self didFailWithError:error];
        }
    }];
}

上記の完了ブロックがコールバックされる前に、メイン状態ハンドラーブロックがFBSessionStateClosed状態で呼び出されます。それまでの間、Facebook SDKは上記のエラーを記録しました。

システムをリセットする方法が見つかりません。私もその原因を本当に理解していません。

誰かが光を当ててください。

37
tarmes

デバイス上のFacebookアカウントは、サーバーおよびアプリ/ SDKのキャッシュと同期しなくなりました。これは、ACAccountStoreメソッドrenewCredentialsForAccountを呼び出すことで解決できます。これにより、トークンの状態に関するOSの認識が更新されます。

SDKの次の更新では、SDKは、トークンが無効になったことを示す応答をサーバーから受信すると、このAPIを自動的に呼び出します。 SDKの3.1.0リビジョンでは、アプリケーションはこのAPIを明示的に呼び出す必要があります。コードサンプルは次のとおりです。

ACAccountStore *accountStore;
ACAccountType *accountTypeFB;
if ((accountStore = [[ACAccountStore alloc] init]) &&
    (accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){

    NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
    id account;
    if (fbAccounts && [fbAccounts count] > 0 &&
        (account = [fbAccounts objectAtIndex:0])){

        [accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
            //we don't actually need to inspect renewResult or error.
            if (error){

            }
        }];
    }
}

APIをどこでいつ呼び出すかについて、いくつかのオプションがあります。最も簡単な場所は、アプリケーションの起動時またはビューのロード時に日和見的に呼び出しを行うことです。このアプローチの1つの問題は、多くの場合不必要なネットワークの往復を引き起こすことです。別のオプションは、セッションが終了したことを示すセッション変更通知が発生したときに呼び出すことです。また、多くのアプリケーションは、アプリケーションの起動時にgraph.facebook.com/meなどの基本情報を取得します。その場合、エラー応答の場合にこのメソッドを呼び出すことは、iOSにトークンの更新を依頼する妥当な場所です。状態。

これがお役に立てば幸いです!

76
Jason Clark

私は3時間を無駄にしたことを確認するために別のことをするつもりです:アプリ開発者ではないFBユーザーでログインしようとしている場合は、FBアプリの設定に「サンドボックス」オプションがないことを確認してください...おそらく明らかですが、他の人を数時間節約できれば幸いです。

7
snowdragon

まだ提案されていない場合は、Facebookアプリの 設定パネル にiOSアプリバンドルIDを追加してみてください here

お役に立てれば。

4
Cyupa
[FBSession openActiveSessionWithReadPermissions:nil
 allowLoginUI:YES
 completionHandler:^(FBSession *session, FBSessionState  state, NSError *error) 
    {

       switch (state) {
           case FBSessionStateOpen:
               [self presentPostOptions];
               break;

           case FBSessionStateClosed:
           case FBSessionStateClosedLoginFailed:
               [FBSession.activeSession closeAndClearTokenInformation];
               break;

           default:
               break;
       }

      }];   
1
user4431517

これはFacebook iOS SDKのバグ(3.1.1であっても)であると確信しており、 このバグレポート を提出しました。

サンプルアプリScrumptiousを使用してこのバグを再現しようとしているときに、openActiveSessionWithReadPermissionsを使用している場合は正常に再認証できることがわかりました。ただし、openActiveSessionWithPublishPermissionsを介して公開許可を要求している場合、com.facebook.sdk.error 5

1
Min Kim

Facebook SDK 3.7.1では、まだこの問題がありました。基本的に、これが発生したときにFacebookキャッシュからトークンをクリアすることにしました。このような:

if(state == FBSessionStateClosed ) {
     [FBSession.activeSession closeAndClearTokenInformation];
}
0
Tiago Almeida

Simple Swift 2+ Solutionアクセストークンの検証中のFacebookエラーの場合

// Step 1: Logout 
FBSDKLoginManager().logOut()

// Step 2: Login
FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email"], fromViewController: self, handler: { result, error -> Void in 

// ...

}

このエラーが発生した場合、新しいFacebookセッションを作成する必要があるため、再度ログインする必要があります。

0
fatihyildizhan