Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook Single-Sign On: when user logs out of Facebook app, how do I log out of my app?

I'm completely flabbergasted by the Facebook SDK for Android--it's quite challenging to use effectively. As I understand it, these are the rules for single sign on:

  • If a user has the Facebook app and logs into a third-party app using the SDK, the Facebook app is logged in as well
  • If the user logs out of the third-party app using the SDK, the Facebook app is still signed in (probably for the best)
  • If the user logs out of the Facebook app, the third-party app using the SDK is unaffected

Is there a way, in an Android app using the Facebook SDK, to check and see if the official Facebook app is NOT signed into the same account the Android app is using, and if that is the case, sign out of the Android app... in other words, if you go into the Facebook app and sign out, then go to the third-party app, it will be logged out?

like image 323
Chad Schultz Avatar asked Apr 24 '12 15:04

Chad Schultz


2 Answers

Updated answer

Is there a way, in an Android app using the Facebook SDK, to check and see if the official Facebook app is NOT signed into the same account the Android app is using, and if that is the case, sign out of the Android app...

If I understand this right, you're asking if we can:

  • From your app, check if the official android app is installed
  • if it is installed, check if it is signed into same account as your app
  • if the official app is not signed into your account, sign out your app

Short answer: No, but you can, by writing your own Facebook class

  • Check if the offical FB app isn't installed OR is in logged out state OR is logged into another account.
  • If either is the case, force your app to show login dialog.

Long answer:

Single Single On(SSO) is handled in the Facebook class in the Facebook Android SDK. The Facebook class API doesn't have methods that let you access or modify the SSO process.

In the Facebook class, there are four overloaded public authorize methods. Three of them call the fourth:

public void authorize(Activity activity, String[] permissions,
        int activityCode, final DialogListener listener)

Here, the SSO process starts. It checks for SSO like so:

 // Prefer single sign-on, where available.
    if (activityCode >= 0) {
        singleSignOnStarted = startSingleSignOn(activity, mAppId,
                permissions, activityCode);
    }
    // Otherwise fall back to traditional dialog.
    if (!singleSignOnStarted) {
        startDialogAuth(activity, permissions);
    }

The private startSingleSignOn method checks if the official Facebook app can manage the Auth process:

private boolean startSingleSignOn(Activity activity, String applicationId,
        String[] permissions, int activityCode) {
    boolean didSucceed = true;
    Intent intent = new Intent();

    intent.setClassName("com.facebook.katana",
            "com.facebook.katana.ProxyAuth");
    intent.putExtra("client_id", applicationId);
    if (permissions.length > 0) {
        intent.putExtra("scope", TextUtils.join(",", permissions));
    }

    // Verify that the application whose package name is
    // com.facebook.katana.ProxyAuth
    // has the expected FB app signature.
    if (!validateActivityIntent(activity, intent)) {
        return false;
    }

    mAuthActivity = activity;
    mAuthPermissions = permissions;
    mAuthActivityCode = activityCode;
    try {
        activity.startActivityForResult(intent, activityCode);
    } catch (ActivityNotFoundException e) {
        didSucceed = false;
    }

    return didSucceed;
}

The method creates an explicit intent for the class ProxyAuth in the package com.facebook.katana, which is the offical Facebook app's package. The method then calls validateActivityIntent with the intent as a parameter. It returns true if the service intent resolution happens successfully and the FB signatures match.

We don't have access to the ProxyAuth class source but based on the observed app behaviour you described in your question and comments, it seems that ProxyAuth only completes the auth process if the user is logged in on the official app to the same account as on your app. This means that there is no way to distingush - from your app - between 1) the offical FB app not being installed 2)the official FB app not being in a logged in state, and 3) it being logged into another account.

So you can do this:

  • check if FB app is not installed OR is not logged in OR is logged into another account.
  • If either is the case, log out your app.

But you can't

  • verify that the official FB is installed AND is in logged out state.
  • verify that the official FB app is installed AND is logged into another account.

If what you can do as per above meets your needs to trigger a sign-out, you need to write your own custom Facebook class to add the new logic. The Facebook class in the Facebook Android SDK doesn't extend an abstract class, only Object implicitly, so you need to replicate the Facebook code into your CustomFacebook class and modify it to add code that forces the log-out.

For reference:

Old answer

I'm not sure this answers your question but to force a user log-out with the Facebook Android SDK, use the FORCE_DIALOG_AUTH flag when you call authorize() during auth/login, like so:

mFacebook.authorize(this, PERMS, mFacebook.FORCE_DIALOG_AUTH, new LoginDialogListener());

where mFacebook is an instance of the SDK's Facebook class, and LoginDialogListener implements DialogListener.

If the user logs out, the login dialog will now appear next time the user wants to login or starts your app.

If you don't set the FORCE_DIALOG_AUTH flag the user will be 'automatically' logged in.

like image 195
onosendai Avatar answered Oct 07 '22 10:10

onosendai


Few comments, hope this helps.

Given that Facebook App is the master app, login/logout actions of your (or other) apps will not do any affect. Your app, gains its own access token thru SSO flow, and this wouldn't make any tie with the master app.

Simply; when you complete SSO, you get access_token allocated for your appid with expiration time of ca.2 hours (if you don't ask for offline_access permission).

-- How to check the validity of your token? simplest way is to load me profile with HTTP GET to

https://graph.facebook.com/me?access_token=<access_token>

if your token is invalid, the response will clearly tell you that

-- How to invalidate (aka logout) your token? you can make HTTP GET call to that endpoint, see example

https://api.facebook.com/restserver.php?method=auth.expireSession&format=json&access_token=<access_token>
like image 42
Yilmaz Guleryuz Avatar answered Oct 07 '22 09:10

Yilmaz Guleryuz