1971 active members
  176 are Online

Year

27

Day

307

Time

18:14:02

Guest
Login

Web Services Hub » OAuth 2.0 » Flows » Using OAuth 2.0 for Client-side Applications

Using OAuth 2.0 for Client-side Applications

The Web Service OAuth 2.0 endpoint supports Javascript-centric applications. These applications may access a Resource while the user is present at the application, and this type of application cannot keep a secret.

This article describes how to use OAuth 2.0 when accessing a Resource from a Javascript application.

Overview

This scenario begins by redirecting a browser (popup, or full page if needed) to a SW Combine URL with a set of query parameters that indicate the type of resource access the application requires. Like other scenarios, SW Combine handles the user authentication and consent, and the result is an access token. SW Combine returns the access token on the fragment of the response, and client side script extracts the access token from the response.

The application may access a Resource after it receives the access token.

Important

Your application should always use HTTPs in this scenario.

Forming the URL

The URL used when authenticating a user is https://www2.swcombine.com/ws/oauth2/auth/. This endpoint is accessible over SSL, and HTTP connections are refused. (Note: SSL is not currently setup)

Endpoint Description
https://www2.swcombine.com/ws/oauth2/auth/ This endpoint is the target of the initial request for an access token. It handles active session lookup, authenticating the user, and user consent.

The set of query string parameters supported by the Web Service Authorization Server for client-side applications are:

Parameter Values Description
response_type token Javascript applications should use token. This tells the Web Service Authorization Server to return the access token on the fragment.
client_id the client_id obtained from the Web Service console Indicates the client that is making the request. The value passed in this parameter must exactly match the value shown in the Web Service console.
redirect_uri The redirect_uri values registered at the Application Registration Form Determines where the response is sent. The value of this parameter must match the redirect_uri registered in the Web Service console, or extend it with a path, query string or fragment (for example, if https://www.example.com/oauthcallback is registered, https://www.example.com/oauthcallback/step2 is also accepted). The comparison is not case sensitive. If you omit this parameter, the registered redirect_uri is used.
scope space delimited set of permissions the application requests Required. Indicates the resource access your application is requesting, as a space-delimited list of permission names (for example character_read character_credits, URL-encoded with %20 or +). See the permissions documentation for the available permissions (listed there in upper case; use lower case in the scope parameter). The values passed in this parameter inform the consent page shown to the user. There is an inverse relationship between the number of permissions requested and the likelihood of obtaining user consent.
state any string Indicates any state which may be useful to your application upon receipt of the response. The Web Service Authorization Server roundtrips this parameter, so your application receives the same value it sent. Possible uses include redirecting the user to the correct resource in your site, nonces, and cross-site-request-forgery mitigations.
renew_previously_granted Optional string with value: 'yes' Indicates whether previously granted permissions should be renewed if not explicitly included within the scope parameter. Defaults to not renewing previously granted permissions.

An example URL is shown below.

https://www2.swcombine.com/ws/oauth2/auth/?
scope=character_read%20character_credits&
state=%2Fprofile&
redirect_uri=https%3A%2F%2Fwww.example.com%2Foauthcallback&
response_type=token&
client_id={client_id}

Handling the Response

SW Combine returns an access token to your application if the user grants your application the permissions it requested. The access token is returned to your application in the fragment as part of the access_token parameter. Since a fragment is not returned to the server, client-side script must parse the fragment and extract the value of the access_token parameter.

Other parameters included in the fragment are expires_in, scope and token_type. These parameters describe the lifetime of the token in seconds, the permissions it grants, and the kind of token that is being returned. If the state parameter was included in the request, it is returned in the query string of the redirect_uri, not in the fragment.

An example User Agent flow response is shown below:

https://www.example.com/oauthcallback?state=/profile#access_token=M2XK9D4PQ7VB1N6CJ3HT5RW0LY8FGEZA&expires_in=3600&scope=character_read+character_credits&token_type=Bearer

Other fields may be included in the response. Your application should allow additional fields to be returned in the response. The set shown above is the minimum set.

Below is a Javascript snippet that parses the response and returns the parameters to the server.

// First, parse the fragment (the token) and the query string (the state)
function parseParams(paramString) {
  var params = {}, regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(paramString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2].replace(/\+/g, ' '));
  }
  return params;
}

var fragment = location.hash.substring(1);
var params = parseParams(fragment);
params['state'] = parseParams(location.search.substring(1))['state'];

// And send the token over to the server
var req = new XMLHttpRequest();
// consider using POST so query isn't logged
req.open('GET', 'https://' + window.location.host + '/catchtoken?' + fragment, true);

req.onreadystatechange = function (e) {
  if (req.readyState == 4) {
     if(req.status == 200){
       window.location = params['state']
   }
  else if(req.status == 400) {
        alert('There was an error processing the token.')
    }
    else {
      alert('something else other than 200 was returned')
    }
  }
};
req.send(null);

This code sends the parameters received on the fragment to the server (the /catchtoken endpoint in this example) using XMLHttpRequest over an HTTPs channel, then sends the user to the location given in the state parameter. If other Javascript code in your application needs to make calls to a Resource, your application may also store the access token in the browser.

Error response

The Web Service Authorization Server returns an error if the user did not grant your application the permissions it requested. The error is returned in the query string of the redirect_uri, not in the fragment.

An example error response is shown below:

https://www.example.com/oauthcallback?error=access_denied&state=/profile

Validating the Token

Tokens received on the fragment MUST be explicitly validated. Failure to verify tokens acquired this way makes your application more vulnerable to the confused deputy problem.

You can validate a token by making a web service request to an endpoint on the Web Service Authorization Server and performing a string match on the results of that web service request.

TokenInfo Validation

Verifying a token using the Web Service Authorization Server endpoint is relatively simple. Your application includes the access token in the access_token parameter for the following endpoint:

Endpoint Description
https://www2.swcombine.com/ws/oauth2/tokeninfo/ Accepts an access token and returns information about that access token including: which application was it issued to, the intended target of the token, the scopes the user consented to, the remaining lifetime of the token, and the user id.

Below is an example of such a request:

https://www2.swcombine.com/ws/oauth2/tokeninfo?access_token=M2XK9D4PQ7VB1N6CJ3HT5RW0LY8FGEZA

The TokenInfo endpoint will respond with a JSON array that describes the token or an error. Below is a table of the fields included in the non-error case:

Field Description
audience The application that is the intended target of the token.
scope The space delimited set of scopes that the user consented to.
user_id The value of this field (in the form 1:<character id>) is an immutable identifier for the logged-in character, and may be used when creating and managing user sessions in your application. This identifier is the same regardless of the client_id.
expires_in The number of seconds left in the lifetime of the token.

On the wire, the response looks similar to the following:

JSON

{
  "audience":"a1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
  "user_id":"1:123456",
  "scope":"character_read character_credits",
  "expires_in":436
}

XML

<?xml version="1.0" encoding="utf-8"?>
<TokenInfo>
    <audience>a1b2c3d4e5f60718293a4b5c6d7e8f9012345678</audience>
    <user_id>1:123456</user_id>
    <scope>character_read character_credits</scope>
    <expires_in>436</expires_in>
</TokenInfo>

Note: When verifying a token, it is critical to ensure the audience field in the response exactly matches your client_id registered in the API console. This is the mitigation for the confused deputy issue, and it is absolutely vital to perform this step.

If the token is not recognised (for example it has been tampered with or the permissions revoked), the Web Service Authorization Server will respond with an error. The error surfaces as a 400 status code, and a JSON body as follows:

JSON

{"error":"invalid_token"}

XML

<?xml version="1.0" encoding="utf-8"?>
<error>
    invalid_token
</error>

An expired token results in a 401 status code with a token_expired error. A request without an access_token parameter results in a 400 status code with an invalid_request error, and a request for a character that is currently unable to use Web Services (for example a dead, inactive or banned character) results in a 400 status code with an invalid_character_status error. By design, no additional information is given as to the reason for other failures.

Calling a Resource

After your application has obtained an access token, your application can access a Reource by including it in either an access_token query parameter or an Authorization: OAuth HTTP header.

For example, a call to the Character Resource using the access_token query string parameter looks like the following:

GET https://www2.swcombine.com/ws/v2.0/character/Testing%20Character?access_token=M2XK9D4PQ7VB1N6CJ3HT5RW0LY8FGEZA

A call to the same resource using the access_token Authorization: OAuth HTTP header looks like the following:

GET /ws/v2.0/character/Testing%20Character HTTP/1.1
Authorization: OAuth M2XK9D4PQ7VB1N6CJ3HT5RW0LY8FGEZA
Host: www2.swcombine.com

You can try either out in the CURL command line application. Here's an example of the query string parameter option:

curl https://www2.swcombine.com/ws/v2.0/character/Testing%20Character?access_token=M2XK9D4PQ7VB1N6CJ3HT5RW0LY8FGEZA

And the HTTP header option:

curl -H "Authorization: OAuth M2XK9D4PQ7VB1N6CJ3HT5RW0LY8FGEZA" https://www2.swcombine.com/ws/v2.0/character/Testing%20Character