Native mobile app for Salesforce Communities - Part 2 (Authentication)

Gist: After an overview in Part 1, we now dive into the nuts and bolts of Authenticating a native mobile app with Salesforce Communities, technical architecture and look at some code for a "how to" with Titanium Appcelerator.

Now that we are ready to build our native mobile application, there are three key technical areas that the majority of our work will focus on:

  • Authenticate and Authorize (via OAuth)
  • Salesforce Integration (via REST API)
  • Mobile UX / App (using Appcelerator)

Prerequisites:

  1. A published Communities instance with a working Social Sign-on authentication setup (Ref.)
  2. A machine with Titanium Studio installed and set up with iOS and Android emulator (Code here is for iOS)
  3. Reasonable understanding of web programming, JavaScript and Salesforce REST API

Authenticate and Authorize (OAuth)

A Platform user OAuth login where a user id and password is sent to Salesforce looks like this...

https: //login.salesforce.com/services/oauth2/token?grant_type=password&client_id=your_app_id&client_secret=your_app_secret&username=your_username&password=your_password

A Communities user OAuth login uses an instance specific URL instead of a generic 'login.salesforce.com' to ensure that the login request is sent to your specific community and ensures that a branded login page can be displayed.

https://acme.force.com/customers/services/oauth2/authorize?response_type=token&client_id=your_app_id&redirect_uri=your_redirect_uri

Note that this call is different because Communities only supports a 'User-Agent OAuth' authentication flow. This means that a Salesforce UI conducts the entire sign-on process and user credentials are never handled by the mobile app directly. For more details, there is an excellent read by Tom Gersic here.

Any integration with a Social Sign-on process such as Facebook or JanRain is orchestrated by Salesforce and all that configuration is handled on the Salesforce' Server side as shown above.

So, what does it For our mobile app, this means that our first screen will need to load a web view and redirect it to the Salesforce communities instance login page.

Communities Instance specific Login page

While doing this with Titanium alloy, we will first declare the webview. Here is how my index.xml (under Titanium project’s “View” folder) looks like.

<Alloy>
<Window class="container">
<WebView id="webViewLogin" url=" https://my-communities-instance.na11.force.com/my-community-name/services/oauth2/authorize?response_type=token&client_id=MY_CLIENT_ID&redirect_uri=https://login.salesforce.com/services/oauth2/success "/>
</Window>
</Alloy>

In Titanium, index.xml serves as the entry point for the mobile app. By putting the code here, we ensure that the webview is the first UI this app loads (and that in turn, will load the Community specific login page).

Once the authentication is successful, Salesforce will return a success URL that contains the Access and refresh token. We will parse out these tokens and use them for our REST API calls. Here is the sample code from the controller index.js file.

$.webViewLogin.addEventListener('load', function (e) {

Ti.API.info("Webview loaded...");
Ti.API.info(e.url);


if (e.url.indexOf('/oauth2/success') !== -1) {

var hash = e.url.split('#')[1];
var elements = hash.split('&');


for (var i = 0, l = elements.length; i < l; i++)

{
var element = elements[i].split('=');
switch (element[0]) {

case 'access_token':

Ti.API.info('access token' + Ti.Network.decodeURIComponent(element[1]));
}
});

break;
//You can do the same to parse out refresh token, instance URL etc.

default: break;

}
}

$.index.close();

//This HTTP client will be used for all HTTP calls.

var loader = Titanium.Network.createHTTPClient();

Alloy.Globals.loader = loader;

Alloy.createController('main').getView().open();

}

});

$.index.open();

Typically, mobile apps would store these tokens in a durable storage so that the user only logs in once, and the next time they access this app, it can use the existing access token or get a new one using the refresh token, and seamlessly log them in background.

The app must appropriately secure / encrypt such information. Titanium supports local storage via db, properties and collections.

Let's look at how we can build our native mobile UI with custom branding (Part 3) and use the Salesforce communities issued Access token to interact with its REST web services (Part 4), and offer our customers a differentiated mobile user experience.