Saturday, October 24, 2015

OpenAM : How to exchange for a long-lived access token from Facebook?

I have a customer who has a big data marketing engine running and they request for more information from Facebook to gather insights into their customers.




By default, when a user authenticates with Facebook via OpenAM Login Page, only a short-lived access token is captured.

There are 2 issues:

  1. The marketing engine will only run nightly/weekly. The short-lived access token would have expired then.
  2. The access token, even if it has not expired, is not persisted. Thus the marketing engine has no means to pick it up.


I did some research and this is what is required to exchange a short-lived access token with a long-lived access token.



You must exchange this short lived token with a long lived token by invoking a GET request to the following URL: 

https://graph.facebook.com/v2.0/oauth/access_token?grant_type=fb_exchange_token&client_id=[APP_ID]&client_secret=[APP_SECRET]&fb_exchange_token=[SHORT_LIVED_TOKEN] 

Where: 
APP_ID is your application id. 
APP_SECRET is your application secret. 
SHORT_LIVED_TOKEN is the short lived user access token received in the previous step. 

What comes back: 
The JSON response will contain the long lived access token.



To achieve customer's requirement, we can write some custom codes in Post-Authentication Processing module.

    @Override
    public void onLoginSuccess( Map requestParamsMap, HttpServletRequest request,
        HttpServletResponse response, SSOToken ssoToken )
            throws AuthenticationException {

         if (authentication module is Facebook) {

              // THIS IS KEY! Without it, there is no way to exchange for a long-lived
              // access token
              // this is short-lived access token returned from Facebook at OAuth 
              // authentication module
              String accessToken = ssoToken.getProperty
                             (OAuthParam.SESSION_OAUTH_TOKEN);

              // clientId, clientSecret, tokenServiceUrl 
              // quick and dirty is to hardcode; 
              // otherwise, read OAuth.java, OAuthParam.java and OAuthConf.java
              String clientId = ...;
              String clientSecret = ...;
              String tokenServiceUrl = ...;

              // follow the URL format above (highlighted in blue)
              String url = getFormattedTokenServiceUrlForFBLongLivedToken
                        (accessToken, clientId, clientSecret, tokenServiceUrl);

              // make a GET call to Facebook to exchange for a long-lived access token
              // methods getContent() and getContentStreamByGET() available 
              // in OAuth.java (no need to reinvent wheel; modify a bit will do)
               String longLivedToken  =  getContent(url);

              // Need to strip: 
              //    e.g. access_token=[LONG-LIVED-ACCESS-TOKEN]&expires=5148647
              longLivedToken = longLivedToken.substring(13,longLivedToken.indexOf("&"));

              // Persist FB long-lived access token to user's LDAP entry
              updateFBLongLivedAccessToken (longLivedToken, ssoToken);

          }

    }


Nice!

No comments:

Post a Comment