Developing OAuth 2.0 Library with Apex – Day 3

This is the third and final part of the series Developing OAuth 2.0 Library with Apex. After this one should be ready to actually make calls to any 2.0 compliant provider such as Facebook, Klout ,Dropbox and many more.

If you recall, OAuth authorization is a 2 step process and needs a user interface or a visual force page to perform the actual authorization.
The source code of the page is as follows:

<apex:page controller="OAuthController" action="{!finalAuth}">
<apex:form >
<apex:pageBlock title="Social Application Authorization ">
   <apex:pageBlockSection columns="1">
    <apex:pageBlockSectionItem >
       <apex:outputText value="Application"/>
       <apex:selectList value="{!service}" size="1">
         <apex:selectOptions value="{!serviceNames}"/>
       </apex:selectList>
    </apex:pageBlockSectionItem>
    <apex:pageBlockSectionItem >
      <apex:outputText rendered="{!message!=null}" value="{!message}"/>
    </apex:pageBlockSectionItem>
     <apex:commandLink action="{!doAuthorization}" value="Authorize" id="lnCommandLink" target="_blank" />
  </apex:pageBlockSection>
 </apex:pageBlock>
</apex:form>
</apex:page>

The controller code is as follows:

public class OAuthController {
public String service { get; set; }
//Services Picklist
String message=null;
private static List<selectOption> VIEW_SERVICES = new SelectOption[]{
new SelectOption('LinkedIn','LinkedIn'),
new SelectOption('Facebook','Facebook'),
new SelectOption('Twitter','Twitter')
};
public List<SelectOption> getServiceNames(){
return VIEW_SERVICES;
}
public String getMessage(){
return message;
}
public PageReference finalAuth(){
//OAuth_1_0 oa = new OAuth_1_0('Twitter');
String oauth_token = ApexPages.currentPage().getParameters().get('oauth_token');
String oauth_verifier = ApexPages.currentPage().getParameters().get('oauth_verifier');
String oauth_code = ApexPages.currentPage().getParameters().get('code');

//message=oauth_token+' '+oauth_verifier;
//Now call auth service to get authorized tokens
if (oauth_code != null){
    oauth_code = oauth_code+'#_=_'; //Facebook anomaly?
    UserTokens__c userToken = [select Id,OAuth_Service__c,Token__c,secretToken__c from UserTokens__c
                              where isAuthorized__c = false and CreatedBy.Name=:userInfo.getName()];
    OAuth_Service__c oservice = [select Name,AccessTokenUrl__c from OAuth_Service__c
                                where Id = :userToken.OAuth_Service__c LIMIT 1];
    OAuth_2_0 oa = new OAuth_2_0(oservice.Name);
    String authorizedStr=oa.getAuthorizedReqToken(oauth_code);
    String authUserToken=authorizedStr.split('&')[0].split('=')[1];
    //String authUserToken=authorizedStr;
    userToken.Token__c = authUserToken;
    userToken.isAuthorized__c = true;
    upsert userToken;
    message='Authorization Successful..'+'Access Token:'+authUserToken;
}
return null;
}
public PageReference doAuthorization(){
//This is a 2 Legged authorization
// Get UnAuthorized Tokens
System.debug('========================== Service:'+service);
PageReference authPage;
OAuth_Service__c os = [select Id,Name,OAuth_Version__c,ReqTokenUrl__c,AuthUrl__c from OAuth_Service__c where Name = :service];
if (os.OAuth_Version__c != NULL && os.OAuth_Version__c.equalsIgnoreCase('2.0')){
    List<UserTokens__c> unauthorizedTokenList=[select Id from UserTokens__c
                                               where CreatedBy.Name=:userInfo.getName()
                                               and OAuth_Service__c = :os.Id];
    delete unauthorizedTokenList;
    OAuth_2_0 oa = new OAuth_2_0(service);
    UserTokens__c userToken = new UserTokens__c();
    userToken.Name = service+' '+userInfo.getName();
    userToken.OAuth_Service__c = os.Id;
    userToken.isAuthorized__c = false;
    insert userToken;
    String authURL = oa.getUnauthorizedReqToken();
    authPage=new PageReference(authURL);
    authPage.setRedirect(true);
}
return authPage;
}
}

I have also created a TAB called “Authorize Social Media”.
This is how VF page and the whole authorization process works:
STEP 1:

oauth1

I selected Facebook and clicked on Authorize Link. Facebook server is sent an HTTP request to send temporary token so that once the user confirms, it can send a final Token.

STEP 2:

If you are already logged in to Facebook, It will grant authorization immediately else it will show you the following screen:

oAuth2

Note that it is showing the name of my App which is fb2SF (Facebook to Salesforce).

Once you logged in successfully it will create a permanent token and return to Visualforce Page (Since it is a call back URL) as follows:

oAuth4

Actual Token is masked for security reasons. This token is now saved in Salesforce for this user. The token MUST be securely guarded and Object permissions must be managed properly. Until the Authorization is revoked, this token will be used to perform Facebook operations via API.

Object Definition to store access tokens for the user is as follows:

Object is called UserTokens__C and the fields are:

isAuthorized__c           Checkbox,
OAuth_Service__c     Master-Detail(OAuth_Service),
secretToken__c           Text(255),
Token__c                          Text(255)

This concludes the authorization part. If you think I need to write how to make actual meaningful API calls, please let me know via comments.

6 thoughts on “Developing OAuth 2.0 Library with Apex – Day 3

  1. Well documented and well written. Do you have the OAuth_1_0 class available for the twitter oAuth?
    I am looking to build a generic toolset for oAuth and this is a great resource!!! Thanks

  2. This is very usefull and important post. I also excited to know how api calls is working. Iam working on api calls but feeling dificulties moving ahead. Please post as soon as possible the API calls document with example.

    Thanks

  3. Hello there, just became alert to your blog through Google, and
    found that it is really informative. I am going to watch out for brussels.
    I will be grateful if you continue this in future. Many people will
    be benefited from your writing. Cheers!

  4. I am not able to use “UserTokens__c and “OAuth_Service__c” in my apex code. How to access these objects in my code?

Leave a comment