For up-to-date product documentation, see the IBM MobileFirst Foundation Developer Center.


JavaScript custom resource-request implementation sample

A JavaScript sample for acquiring data from a protected resource by using the MobileFirst WLAuthorizationManager class.

The sample implements a standard OAuth flow: first, a resource request is sent without an access token. This request is expected to fail with an authorization error. Then, WLAuthorizationManager is used to obtain an access token for the resource's protecting scope, and the request is sent again with the obtained access token as an authorization header. The resource request is created by using a standard XMLHttpRequest object.

function sendCustomRequest() { sendRequest('http://localhost:3000/v1/apps/1234/test', null) .always( function(response) { alert(response); } ); } /** * Sends a request with the provided access token to the specified protected-resource URL. **/ function sendRequest(url, accessToken) { // Use JavaScript promises for asynchronous operations var dfd = WLJQ.Deferred(); // Create the custom resource request var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { var status = xhr.status; if (status >= 200 && status <= 299) { dfd.resolve(xhr.responseText); } else { var headers = xhr.getAllResponseHeaders(); // Check whether access to the resource requires authorization if (WLAuthorizationManager.isAuthorizationRequired(status, headers)) { if (status === 409) { // Server-conflict error // Resend the request sendRequest(url, accessToken) .then( function(response) { dfd.resolve(response); }, function(error) { dfd.reject(error); } ); } else if (status === 401) { // Invalid access token, or no access token // Check whether the access token is invalid if (isInvalidTokenError(xhr)) { // Clear the invalid access token WLAuthorizationManager.clearAccessToken(accessToken).always( function() { // Obtain a valid access token and resend the request resendWithAccessToken(null); }); } else { // Obtain a valid access token and resend the request resendWithAccessToken(null); } } else { // status = 403 - insufficient-scope error // Get the resource scope from the response var scope = WLAuthorizationManager.getResourceScope(headers); // Obtain an access token for the scope resendWithAccessToken(scope); } } else { // Unexpected error dfd.reject("Failure - received response " + xhr.responseText); } } } }; // If an access token was obtained, add the token to the request as an authorization header if (accessToken !== null) { xhr.setRequestHeader("Authorization", accessToken.asAuthorizationRequestHeader); } xhr.send(); return dfd.promise(); function resendWithAccessToken(scope) { WLAuthorizationManager.obtainAccessToken(scope) .then( function(accessToken) { // The access token was obtained successfully. // Construct the request again, and add the access token as an authorization header sendRequest(url, accessToken) .then( function(response) { dfd.resolve(response); }, function(error) { dfd.reject(error); } ); }, function(error) { // Failed to obtain an access token. Reject the request. dfd.reject(error); } ); } } function isInvalidTokenError(xhr) { var authHeader = xhr.getResponseHeader('WWW-Authenticate'); return (authHeader.indexOf("invalid_token") >= 0); }

Parent topic: Sample custom resource-request implementations using WLAuthorizationManager