9

Background

I currently have a hybrid iOS app that runs locally (index.html in the xcode app) that essentially provides a basic start page and login flow instructions that lead off to a force.com web app.

To obtain the refresh token for the first time, I want the start page to give instructions and take users into the initial login flow using either authenticate or OnDeviceReady functions that come out of the box with the hybrid sample apps. However, if the user has already gone through the initial login flow and has a refresh token, I really just want to redirect them to the app.

Question

Can I use some JS method to find out if I already have a refresh token and then drive the logic for when to show the login/instructions page and when to redirect? I can only seem to find methods in the SDK that initiate the authentication flow.

Here is my JS in index.html:

jQuery(document).ready(function() {
    //Add event listeners and so forth here
    logToConsole("onLoad: jquery ready");
    $("#loginButton").click(onDeviceReady);

});

// When this function is called, Cordova has been initialized and is ready to roll 
function onDeviceReady() {
    logToConsole("onDeviceReady: Cordova ready");

    //Call getAuthCredentials to get the initial session credentials
    cordova.require("salesforce/plugin/oauth").getAuthCredentials(salesforceSessionRefreshed, getAuthCredentialsError);
    //register to receive notifications when autoRefreshOnForeground refreshes the sfdc session
    document.addEventListener("salesforceSessionRefresh",salesforceSessionRefreshed,false);

    //enable buttons
    regLinkClickHandlers();
}


function salesforceSessionRefreshed(creds) {
    logToConsole("salesforceSessionRefreshed");

    // Depending on how we come into this method, `creds` may be callback data from the auth
    // plugin, or an event fired from the plugin.  The data is different between the two.
    var credsData = creds;
    if (creds.data)  // Event sets the `data` object with the auth data.
        credsData = creds.data;

    logToConsole(credsData.accessToken);

    window.location = "https://test.salesforce.com/services/auth/sso/00Dn0000000CoZnEAK/Power_of_Us_Hub_Sandbox?community=https://pubdev-powerofus.cs30.force.com&startURL=/one/one.app";

}
  • Have you had a look at the auth.js file (vs. auth_local.js) included in the smart sync JS lib of the Mobile SDK ? – altius_rup Mar 22 '14 at 11:52
2

The long story

Let's trace what's going on. There's basically 3 layers in a hybrid app:

  1. Your code
  2. The Salesforce Cordova Javascript Interface *1
  3. The Salesforce Cordova Plugin (native, for either iOS or Android) *2 *3

First, your code calls

cordova.require("salesforce/plugin/oauth").getAuthCredentials(...,...);

That ends up in layer 2, the Salesforce Cordova Javascript Interface, here: https://github.com/forcedotcom/SalesforceMobileSDK-Shared/blob/31984ae536783bdb57218af2aa02e77cd548ab41/libs/cordova.force.js#L273

Where it calls layer 3, the Cordova plugin, at getAuthCredentials in the com.salesforce.oauth Cordova service.

When we look that up, we can see that the com.salesforce.auth service is actually the SalesforceOAuthPlugin plugin. See https://github.com/forcedotcom/SalesforceMobileSDK-iOS/blob/424cc6a322068e6457b23910ede39af5c3e5992a/shared/hybrid/config.xml#L45

Drilling deeper down, we see that it will try to fetch cachedCredentials, and if not, it will authenticate first, then send the credentials back. ("// If authDict does not contain an access token, authenticate first. Otherwise, send current credentials.")

Once the credentials arrive, your code in layer 2 and then in layer 1 will receive the credentials (including refresh token). They will be in the creds object in the salesforceSessionRefreshed(creds) function.

There is no way in layer1 to only ask for "do I have a refresh token?" without the application trying to log in immediately.

You might be able to see if there's a refresh token stored somewhere via document.cookie or some localStorage keys?

TL;DR

There is no way to only ask for "do I have a refresh token?" without the application trying to log in immediately.

Whenever you call getAuthcreentials, it will try to login, using a refreshtoken if it had one (i.e. not showing a login screen), or via the visual login flow in other cases, and if that worked, it will execute the callback, i.e. your salesforceSessionRefreshed(creds) function, with the login credentials as its argument.

You might be able to see if there's a refresh token stored somewhere via document.cookie or some localStorage keys?


*1 https://github.com/forcedotcom/SalesforceMobileSDK-Shared/blob/31984ae536783bdb57218af2aa02e77cd548ab41/libs/cordova.force.js

*2 In an HTML5 app within VF, you would use only a Javascript wrapper, not the Cordova Plugin, obviously. See the Salesforce Mobile SDK (https://github.com/forcedotcom/SalesforceMobileSDK-Shared/blob/31984ae536783bdb57218af2aa02e77cd548ab41/libs/forcetk.mobilesdk.js)

*3 for iOS: https://github.com/forcedotcom/SalesforceMobileSDK-iOS

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.