Connect IBM Worklight hybrid mobile apps to LinkedIn services

Use IBM Worklight HTTP adapters and OAuth to securely connect to LinkedIn APIs

LinkedIn offers a set of exposed APIs to allow third-party web and mobile applications to call LinkedIn services on an application user's behalf. In this article, IBM® Worklight® developers learn how to write two HTTP adapters to connect a hybrid mobile app to LinkedIn services. The first adapter uses the OAuth standard to securely process authentication and authorization requests between LinkedIn and an application user. The second adapter uses OAuth tokens to send authorized requests to LinkedIn services.

Share:

Lisa Seacat DeLuca, Mobile Software Engineer, IBM Master Inventor, IBM

Photo of Lisa Seacat DeLucaLisa is a Mobile Software Engineer and Master Inventor at IBM, working on mobile application development and open source technologies within IBM Open Technology and Cloud Performance. Lisa is a committer for the Apache Cordova open source project. With more than eight years of enterprise software development experience, Lisa holds a Master of Science in Technology Commercialization from the University of Texas and a Bachelor of Science in Computer Science from Carnegie Mellon University. Follow Lisa on Twitter @LisaSeacat or through her website: lisaseacat.com.



05 March 2014

Also available in Chinese Russian

IBM Worklight developers have access to all of the features that are found in Apache Cordova, an open source mobile development platform for building native mobile applications with HTML, CSS, and JavaScript. Apache Cordova abstracts essential native device APIs, making them more accessible to mobile developers. In this article, you get a hands-on introduction to using Cordova's features for hybrid mobile application development with IBM Worklight and the LinkedIn service APIs.

First, I introduce you to Cordova's InAppBrowser plug-in. The InAppBrowser plug-in helps you implement the OAuth standard for mobile apps by handling the initial client authorization and receiving the response code from the OAuth back-end service. You set up the InAppBrowser plug-in, configure it for OAuth, and use it as a secure authorization pipeline to integrate LinkedIn APIs with the hybrid mobile demo application.

Next, you build two IBM Worklight HTTP adapters that connect your hybrid mobile application to LinkedIn's API services. You'll configure your HTTP adapters to start the OAuth secure authorization procedure, retrieve and save an access token, and use the token for future API calls from your mobile app to LinkedIn's service APIs.

This article assumes that you are familiar with the OAuth 2.0 security standard, JavaScript, HTML, HTTP, and general API access techniques. Examples are based on IBM Worklight and use Worklight's HTTP adapter framework to connect to LinkedIn service APIs. See the Resources section to learn more about these and other mobile development technologies.

About the demo application

The LinkedIn demo application enables a user to find member profiles on LinkedIn and extend an invitation to connect. For this article, the demo application is run in an Android emulator or device, which you need to set up and configure before you start the article steps. Download the demo application project code to get started.

Getting started: OAuth and LinkedIn

To connect your hybrid mobile application to the LinkedIn APIs, you need to register the application with LinkedIn. After your application is registered, you will receive a set of LinkedIn OAuth keys, which the LinkedIn API uses to authenticate your application and allow it to make API calls. In this case, you connect your hybrid mobile application to LinkedIn to send an invitation on behalf of an app user.

The first step is to register the application:

  1. Go to the LinkedIn Developer Network, where you are asked to log in with your LinkedIn ID or register a new account.
  2. After you log in, you see a window like the one shown in Figure 1. Click Add New Application and complete the required information, as I've done for the LinkedIn demo (Company: IBM and Application Name: Mentorship Expressway).
    Figure 1. Add an application
    A screen capture of the LinkedIn application registration page.
  3. Next, you see a window with the OAuth user agreement. This agreement establishes the default permissions that a user is asked to agree to before your application can access his LinkedIn account. For the inviteContact API call to work, the user must accept the w_messages permission. Select w_messages as shown in Figure 2.
    Figure 2. Select the OAuth user agreement
    Screen capture of setting up the LinkedInOAuth user agreement.

    Click to see larger image

    Figure 2. Select the OAuth user agreement

    Screen capture of setting up the LinkedInOAuth user agreement.
  4. Click Add Application.
  5. Write down the API Key and Secret Key from the next window that appears:
    Figure 3. LinkedIn OAuth keys for a new application
    Screen capture of a successful application registration that leads to a new pair of keys.

OAuth and the InAppBrowser plug-in

The OAuth security standard is commonly used to connect web-based applications that run on the Internet. But in the case of mobile development the code isn’t hosted on a particular URL; instead, it runs on an individual user’s mobile or client device. For mobile devices, the OAuth standard typically requires a redirect URI that can receive OAuth tokens. Server-side code that is accessed through the URI interprets a received OAuth token and completes the OAuth handshake. The server-side code passes the received response code to a request to securely obtain an access token, which it then uses for future secure API calls. In the case of a client mobile application, no server-side redirect URI or piece of code can process the OAuth tokens, which is why you need Apache Cordova’s InAppBrowser plug-in. The necessity of using an embedded browser for mobile apps introduces a few more steps to the OAuth secure authorization flow, which I discuss later.

OAuth's secure authorization flow

Next, run a test of the authorization flow between the newly registered application and LinkedIn. The first step in the OAuth flow is to send your application's clientid, in the form of an OAuth API key, to LinkedIn's OAuth service. You retrieve a response code, which you can then use to retrieve an access token.

Because you are using Apache Cordova's InAppBrowser plug-in to initiate the OAuth flow, you can't test the application's authorization by using IBM Worklight in a browser. Instead, run a test using an Android device emulator or physical device.

InAppBrowser for iOS?

See the Apache Cordova documentation to find out how to include plug-ins for operating systems and platforms other than Android.

By default, all new IBM Worklight projects have the Cordova plug-ins enabled. Follow these steps to verify the InAppBrowser plug-in on an Android emulator or device:

  1. Expand your project's android directory.
  2. Choose native.
  3. Open the res > xml > config.xml file.
  4. Verify that the plug-in's parent element includes the InAppBrowser plug-in:
    <plug-in name="InAppBrowser" value="org.apache.cordova.InAppBrowser" />

Next, open an Apache Cordova InAppBrowser window. Listing 1 shows the source code to launch an InAppBrowser.

Listing 1. Launch Apache Cordova'sInAppBrowser
var authUrl = 'https://www.linkedin.com/uas/oauth2/authorization?' + $.param({
                    response_type: 'code',
                    state: '__randomStateChars______',
                    client_id: ‘LINKEDIN_OAUTH_KEY’,
                    redirect_uri: ‘__anyURLHereDoesntMatter___’
        });
        var authWindow = window.open(authUrl, '_blank', 'location=no,toolbar=no');

When the code in Listing 1 is initialized, the client device opens a new window to LinkedIn's consent page. The user is asked to log in to his LinkedIn account and allow or deny the application's request to access services on LinkedIn. The LinkedIn authorization page is shown in Figure 4.

Figure 4. LinkedIn's authorization request
A screen capture of the LinkedIn authorization page.

The authorization request is standard within the OAuth flow. Notice that the LinkedIn authorization page lists all of the APIs that the application would like to access. Once authorized, your example app is able to use two LinkedIn APIs (Profile and Invitation) to locate a member profile and send an invitation from the user to a LinkedIn contact.


Getting the OAuth access token

Under the hood, the OAuth flow responds to the user's authorization by attempting to return an access token to a redirect URI. Because you run your app on a mobile client device, you need to intercept and get the returned code from the mobile browser URL. Listing 2 shows the JavaScript event listener for the OAuth return code.

Listing 2. JavaScript listener for OAuth return code
authWindow.addEventListener('loadstart', function(e) { 
var url = e.url;
					
	var code = /\?code=(.+)$/.exec(url);
	var error = /\?error=(.+)$/.exec(url);
	
	if (code || error) {
		authWindow.close();
	}
				 
if (code) {
		LinkedInOAuth.getAccessToken(code[1]);
		WL.Logger.debug("LinkedIn AUTH CODE: " + code[1]);
	} else if (error) {
		//handle error here
		deferred.reject({error: error[1]});
	}
});

The event listener in Listing 3 monitors the URL of the InAppBrowser window. As soon as it sees the return code, it intercepts and sends it to another method: LinkedInOAuth.getAccessToken(). If the event listener doesn’t appear to fire, it might be because the code was executed before the device was ready. Make sure that Apache Cordova is ready before you make the return code call.

More about OAuth and LinkedIn

See Resources for more details about LinkedIn's OAuth flow.

In the getAccessToken() method, you invoke a Worklight HTTP adapter, which you use to retrieve the OAuth access token. You need two IBM Worklight HTTP adapters for this application example: one to handle the OAuth flow and another to call the LinkedIn APIs.


IBM Worklight adapters for LinkedIn

Build the Worklight HTTP adapters that connect your hybrid mobile app to the LinkedIn API services. The adapters handle the OAuth flow and call the LinkedIn APIs.

Create an adapter for LinkedIn's OAuth services

First, create the IBM Worklight HTTP adapter for LinkedIn's OAuth services. Follow these steps to create the adapter:

  1. Expand your Worklight project so that you can view the adapters folder.
  2. Right-click on adapters and then select New > Worklight Adapter, as shown in Figure 5:
    Figure 5. Create an Adapter
    Screen capture of creating an IBM Worklight HTTP adapter.
  3. In the new dialog window that opens, select your project from the Project name drop-down menu and select HTTP Adapter from the Adapter type menu. Give your adapter a name. The adapter for the LinkedIn OAuth flow is called LinkedInOAuth:
    Figure 6. New Worklight adapter window
    Screen capture of naming the adapter.
  4. Click Finish.
  5. A new directory is displayed under the adapters directory with the three files that comprise the HTTP adapter, as shown in Figure 7:
    Figure 7. New adapter directory
    Screen capture of the new directory folder and its files.
  6. Double-click the LinkedInOAuth.xml file to open it.
  7. Next, update the protocol, domain, and port to work with the LinkedIn OAuth services. The LinkedIn OAuth services require the HTTPS protocol and the default HTTPS port of 443, as specified in Listing 3:
    Listing 3. LinkedInOAuth XML adapter definition changes
    <protocol>https</protocol>
    <domain>www.linkedin.com</domain>
    <port>443</port>
  8. Next, open the LinkedInOAuth-impl.js file. Create a method to receive the initial return code from LinkedIn's OAuth service and retrieve the access token:
    Listing 4. getAccessToken adapter code

    Click to see code listing

    Listing 4. getAccessToken adapter code

    function getAccessToken(code){
    	var client_secret = "___yourclientsecret____";
    	var client_id = "___yourclientid_____";
    	var redirect_uri = "____yourredirecturi____";
    	var params = '?redirect_uri=' + redirect_uri + '&client_secret=' + client_secret + '&client_id=' + client_id + '&grant_type=authorization_code&code=' + code;
    	
    	var input = {
    		    method : 'post',
    		    	path : '/uas/oauth2/accessToken' + params
    		};
    	
    	return WL.Server.invokeHttp(input);
    }
  9. Now go back into the adapter XML file and tell the adapter that the JavaScript for the adapter exists. Open LinkedInOAuth.xml and scroll to the bottom of the file, where an example procedure is already defined. Replace the example with XML that matches the JavaScript method name you created:
    Listing 5. LinkedInOAuth.xml procedure definition
    <procedure name="getAccessToken" connectAs="server"/>

That's it — you created an HTTP adapter that enables LinkedIn's OAuth services to retrieve your app's access token. Next, let's create an adapter to invoke the LinkedIn APIs.

Create an adapter to invoke the LinkedIn API

Many APIs that support OAuth use the same domain and protocol for OAuth services as they do for the rest of their APIs, in which case one adapter is all you need. LinkedIn uses a different domain to access its APIs than it does for its OAuth service, however. So in this case you need to create two adapters: one to retrieve the OAuth access token, and one to call LinkedIn's Profile and Invitations APIs.

Follow steps 1 through 6 that you used to create the LinkedIn OAuth adapter. Give the new adapter a unique name such as LinkedInAPI. After you name the adapter, follow these steps:

  1. Open the LinkedInAPI.xml file. Set the protocol to HTTPS, the domain to api.linkedin.com, and the port to the default SSL port of 443. These details are shown in Listing 6.
    Listing 6. LinkedInAPI.xml connection details
    <protocol>https</protocol>
    <domain>api.linkedin.com</domain>
    <port>443</port>
  2. Again, the next step is to create the JavaScript methods specific to the adapter in progress. In this case, you need methods to call the LinkedIn APIs you want to access, which you define in the LinkedInAPI-impl.js file. In Listing 7 and Listing 8, you see a method to get people, and another to invite a contact to connect on LinkedIn.
    Listing 7. LinkedInAPI-impl.js adapter API calls: getPeople
    function getPeople(acctok){
    	var params = '?oauth2_access_token=' + acctok;
    	var input = {
    		    method : 'get',
    		    path : '/v1/people/~' + params
    		};
    	
    	return WL.Server.invokeHttp(input);
    }
    Listing 8. LinkedInAPI-impl.js adapter API calls: inviteContact
    function inviteContact(acctok, email){
    	WL.Logger.debug("in inviteContact");
    	var params = '?oauth2_access_token=' + acctok;
    	var bodyjson = {
    			  "recipients": {
    				    "values": [
    				    {
    				      "person": {
    				        "_path": "/people/email=" + email
    				       }
    				    }]
    				  },
    				  "subject": "Invitation to connect",
    				  "body": "Invitation message.",
    				  "item-content":{
    				       "invitation-request":{
    				           "connect-type":"friend"
    				       }
    				    }
    	};
    	var bodystr = JSON.stringify(bodyjson);
    	var input = {
    		    method : 'post',
    		    body: { 
    		    		contentType: 'application/json', 
    		    		content: bodystr 
    		    }, 
    		    path : '/v1/people/~/mailbox' + params
    		};
    	
    	return WL.Server.invokeHttp(input);
    }
  3. Just as you did for the previous adapter, your next step is to return to the main adapter XML file. Ensure that both of the procedures are properly defined so that you can invoke them within your application code later on.
    Listing 9. LinkedInAPI adapter XML procedure definition
    <procedure name="getPeople"/>
    <procedure name="inviteContact" />

You've now defined two adapters to connect a Worklight hybrid mobile application to a LinkedIn API. You can follow the same pattern to invoke more LinkedIn APIs through a Worklight adapter. Be sure to define the JavaScript method and place the procedure information within the adapter XML file.


Deploying IBM Worklight adapters

After you create one or more adapters, it is important to deploy them to your Worklight server so that they are accessible by the client code.

  1. Right-click on each of the new adapters.
  2. Select Run As.
  3. Select Deploy Worklight Adapter:
    Figure 8. Deploying the Worklight adapter
    Screen capture of selecting Deploy Worklight Adapter.

When the adapter is successfully deployed you see a message similar to the one in Figure 9, which is printed to the Worklight console:

Figure 9. Adapter build and deploy finished
Screen capture of console message that the adapter build and deploy is finished.

To further verify the application, open your Worklight console and verify that the adapters are deployed within the catalog view:

Figure 10. Worklight console catalog view
Screen capture of the two LinkedIn API adapters in the Worklight console catalog view.

Accessing the LinkedIn APIs

Before you set up the OAuth flow between your mobile app and the LinkedIn API service platform, you must retrieve the OAuth access token and save it to the mobile device.

Retrieve the OAuth access token

You have the response code from your initial OAuth call, but you still need to get an access token to pass in with your calls to the LinkedIn API. Start by invoking the getAccessToken method that you created for your LinkedInOAuth adapter:

Listing 10. Invoking the getAccessToken adapter method
getAccessToken: function(code){
var invocationData = {
		adapter : 'LinkedInOAuth', // adapter name
		procedure : 'getAccessToken', // procedure name
		parameters : [code] // parameters if any
	};
			
	WL.Client.invokeProcedure(invocationData,{
onSuccess : LinkedInOAuth.getAccessTokenSuccess, //success callback
		onFailure : LinkedInOAuth.getAccessTokenFailure // failure callback
	});
},

In Listing 10, you called the LinkedInOauth adapter's getAccessToken procedure with a single parameter, which is the response code you received from the initial LinkedIn OAuth flow. Listing 11 shows an event handler for the getAccessToken result.

Listing 11. Access token success handler
var access_token = "";
getAccessTokenSuccess: function(result){
	var wlresult = result.invocationResult;
			
	if (wlresult){
		var acctok =  wlresult.access_token;
		//optionally save the access token to be used for future calls.
        access_token = acctok;
		
        //optionally publish to listeners that the accesstoken is now set
}			
},
getAccessTokenFailure: function(err){
	WL.Logger.debug(‘Failed to retrieve the access token’);
//optionally publish to listeners that the accesstoken is now set
},

The event handler in Listing 11 returns a result object, which you can use to retrieve the access token that is returned from the call to the LinkedIn service. Saving the access token to the device ensures that the next time you call one of the LinkedIn APIs you don't need to request user approval. For example, you might save the user data to an IBM Worklight JSONStore (see Resources). You also can publish to listeners that the token was received if you want to call an API as soon as the access token was successfully returned.

Calling the LinkedIn APIs

Using the access token that was returned from the previous section, you can now call any number of LinkedIn APIs. You have the adapter code that was developed to call LinkedIn's Profile and Invitation APIs, using the getPeople and inviteContact API calls that you previously set up. Similar to how you called the getAccessToken procedure for the LinkedInOAuth adapter, you can call either one of these two procedures on the LinkedInAPI adapter.

Listing 12 shows an example of calling the inviteContact API call. Notice that the code is almost identical to the code in Listing 10; only the adapter, procedure names, and parameters were changed. In this case, you send in your user's access token and the email of the contact that you want to invite to connect.

Listing 12. LinkedIn inviteContact API call
function addLinkedInContactByEmail(accesstoken, email){
	if (email == '')
		return;
	
if (accesstoken){
		var invocationData = {
			adapter : 'LinkedInAPI', // adapter name
			procedure : 'inviteContact', // procedure name
			parameters : [accesstoken, email] // parameters if any
};
				
		WL.Client.invokeProcedure(invocationData,{
			onSuccess : inviteContactWin, //success callback
			onFailure : inviteContactFail // failure callback
		});
	} else {
		console.log("**********access token is null");
	}
},

And with that your application integration is complete. You successfully set up an OAuth flow between your mobile application and the LinkedIn API services platform.

Handling an UNRESPONSIVE_HOST error

If you study the Mentorship Expressway example application, you might note that the application code is set up to invoke the two IBM Worklight adapters immediately from the wlCommonInit() method. This workaround is for an unusual error that I noticed while I developed the application.

When I invoked my LinkedIn Worklight API adapter, I kept receiving an UNRESPONSIVE_HOST error with the message: “The service is currently not available.” The actual error is shown in Figure 11:

Figure 11. IBM Worklight adapter UNRESPONSIVE_HOST error
Screen capture of unresponsive host error

What is strange is that the same exact code and adapters that are deployed to a different project did not cause this error. I spoke with the IBM Worklight team and we were unable to exactly pinpoint the problem. However, I was able to work around the issue by calling the methods from within the Worklight wlCommonInit() method. If you run across a similar issue, you might consider this workaround.


Conclusion

This article demonstrated how to create an IBM Worklight application that uses OAuth 2.0 to securely access LinkedIn service APIs. While the integration of web applications with the LinkedIn service APIs is fairly straightforward, an embedded browser is required for mobile apps. In the article, you used the Apache Cordova IniAppBrowser plug-in to manage the OAuth flow between LinkedIn and the IBM Worklight hybrid mobile application. The InAppBrowser plug-in provides a redirect URL to receive the initial response code and communicates that code to your Worklight HTTP adapters. Once an access token is acquired and persisted, it can be sent to every future LinkedIn API call from a given mobile application.

With the basic setup and instructions from this article, you can create IBM Worklight hybrid mobile applications that access any number of LinkedIn APIs, and other third-party services that use OAuth for secure authorization. For more information about the technologies that are demonstrated in this article, see Resources.


Download

DescriptionNameSize
Sample code for this articledw-worklight-exampleproject.zip5.1MB

Resources

Learn

Discuss

  • Get involved in the My developerWorks community: Connect with other developerWorks users while you explore the developer-driven blogs, forums, groups, and wikis.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Mobile development on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Mobile development, Security
ArticleID=964880
ArticleTitle=Connect IBM Worklight hybrid mobile apps to LinkedIn services
publish-date=03052014