Kevin Renskers
Kevin Renskers

Reputation: 5912

Facebook iOS SDK 3.2, problems when user removed app from facebook.com

I am using the Facebook iOS SDK (version 3.2), and everything works fine, until a user goes into Facebook and removes the app from the authorizes apps list. At that point, I am still logged in with the cached session, even though it's not actually valid anymore. Forcing a clear of the access token and logging in again also results in the same old access token being used.

Right now in application:didFinishLaunchingWithOptions: I have this code to test the session:

// Relogin with cached session
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
    NSLog(@"We're logged in to Facebook!");

    [FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:NO completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
        NSLog(@"accessToken: %@", session.accessTokenData.accessToken);
        NSLog(@"status: %i", status);
        NSLog(@"error: %@", error);

        switch (status) {
            case FBSessionStateOpen:
                NSLog(@"FBSessionStateOpen");
                NSLog(@"permissions: %@", session.permissions);
                break;

            case FBSessionStateClosed:
            case FBSessionStateClosedLoginFailed:
                [session closeAndClearTokenInformation];
                [Utilities presentMessage:@"Facebook login failed" withTitle:@"Error" level:MessageLevelError];
                break;

            default:
                break;
        }
    }];
}

Every time I start the app, it says I'm still logged in with the user_birthday and email permissions. However, when I try to open https://graph.facebook.com/me?access_token=xxx with the accessToken I got, it returns "Error validating access token: User 123 has not authorized application 123."

Clearing the token with [FBSession.activeSession closeAndClearTokenInformation]; and forcing a new login doesn't help, I always end up with the exact same old accessToken.

There is a similar question (Facebook SDK 3.1 iOS: Handle login if user remove app from Facebook Settings), but it states that "Then, the user closes the iOS app and relaunches it... With this relaunch, the iOS app "is fixed" and detects that the user is no longer logged in." I don't have this behavior at all.

This is how I open the session in the first place:

- (void)openFBSession {
    NSArray *perm = @[ @"user_birthday", @"email" ];

    [FBSession openActiveSessionWithReadPermissions:perm allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
        DLog(@"accessToken: %@", session.accessTokenData.accessToken);
        DLog(@"status: %i", status);
        DLog(@"error: %@", error);

        switch (status) {
            case FBSessionStateOpen:
                DLog(@"FBSessionStateOpen");
                // this is where I need to use session.accessTokenData.accessToken, which is stale
                break;

            case FBSessionStateClosed:
            case FBSessionStateClosedLoginFailed:
                [FBSession.activeSession closeAndClearTokenInformation];
                [Utilities presentMessage:@"Facebook login failed" withTitle:@"Error" level:MessageLevelError];
                break;

            default:
                break;
        }
    }];
}

Upvotes: 3

Views: 1148

Answers (1)

thejaz
thejaz

Reputation: 2773

If the Facebook SDK doesn't find out that the token is invalid while doing Facebook graph api requests on its own, you need to force the iOS to check its token.

This is useful when you call your own server api (and give it the token) and makes call on behalf of the user there. If you find out that the token is invalid there, the only way to tell iOS 6 that the token is invalid is by doing this:

// Only do this if there is native Facebook Account support (iOS 6+)
BOOL isFacebookAccountsAvailable = (&ACAccountTypeIdentifierFacebook != NULL);
if (isFacebookAccountsAvailable) {
    ACAccountStore *accountStore = [ACAccountStore new];
    ACAccountType *accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];
    NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];

    for (ACAccount *fbAccount in fbAccounts)
        [accountStore renewCredentialsForAccount:fbAccount completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
            DLog(@"Renew account error: %@", error.localizedDescription)
        }];
}

Upvotes: 1

Related Questions