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.
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.
The URL used when authenticating a user is https://www.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://www.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 web server 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 exactly match the registered value in the Web Service console (including the http or https schemes, case, and trailing '/'). |
scope | space delimited set of permissions the application requests | Indicates the resource access your application is requesting. 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://www.swcombine.com/ws/oauth2/auth/? scope=character_read%2Fcharacter_write& state=%2Fprofile& redirect_uri=https%3A%2F%2Fwww.example.com.com%2Foauthcallback& response_type=token& client_id=812741506391
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 response include expires_in and token_type. These parameters describe the lifetime of the token in seconds, and the kind of token that is being returned. If the state parameter was included in the request, then it is also included in the response.
An example User Agent flow response is shown below:
https://www.example.com/oauthcallback#access_token=1/fFBGRNJru1FQd44AzqT3Zg&expires_in=3600
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 query string var params = {}, queryString = location.hash.substring(1), regex = /([^&=]+)=([^&]*)/g, m; while (m = regex.exec(queryString)) { params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]); } // 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?' + queryString, 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 using XMLHttpRequest and writes the access token to local storage in the browser. The latter is an optional step, and depends on whether or not the application requires other Javascript code to make calls to a Resource. Also note that this code sends the parameters to the /accepttoken endpoint, and they are sent over an HTTPs channel.
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 fragment.
An example error response is shown below:
https://www.example.com.com/oauthcallback?error=access_denied&state=/profile
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.
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://www.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://www.swcombine.com/ws/oauth2/tokeninfo?access_token=1/fFBGRNJru1FQd44AzqT3Zg
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 is an immutable identifier for the logged-in user, 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:
{ "audience":"8819981768", "user_id":"123456789", "scope":"character_read character_write", "expires_in":436 }
<?xml version="1.0" encoding="utf-8"?> <TokenInfo> <audience>8819981768</audience> <user_id>123456789</user_id> <scope>character_read character_write</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 has expired, 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:
{"error":"invalid_token"}
<?xml version="1.0" encoding="utf-8"?> <error> invalid_token </error>
By design, no additional information is given as to the reason for the failure.
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://www.swcombine.com/ws/v2.0/character/Testing%20Character?access_token=1/fFBGRNJru1FQd44AzqT3Zg
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 1/fFBGRNJru1FQd44AzqT3Zg Host: www.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://www.swcombine.com/ws/v2.0/character/Testing%20Character?access_token=1/fFBGRNJru1FQd44AzqT3Zg
And the HTTP header option:
curl -H "Authorization: OAuth 1/fFBGRNJru1FQd44AzqT3Zg" https://www.swcombine.com/ws/v2.0/character/Testing%20Character