In previous posts, we looked at setting up authentication with OAuth to access FreeAgent’s API. We’ve got something working but a couple of caveats remain when working with it from a rich client.
To summarise the workflow;
- Ask your user to authorise your application (on the target application’s servers).
- You’ll be given an authorisation token from the above. Stash it.
- Exchange your authorisation token for an access token. Stash this too (along with the refresh token).
- Make requests passing along the access token to prove you’re you.
The Authorisation Request
It’s not always clear, but step 1. above is a one time operation. You don’t make this request every time your programmatically want to access the target application. It also implies that the
GET request is made from the browser. There are “out of band” options but in-browser is the simplest.
The Access Token Request
Again, it’s not always clear but the access token request only needs to be made once. In fact, if you’ve successfully retrieved an access token and then request a new one, FreeAgent will error with a basic authentication failure.
HTTP/1.1 401 Unauthorized Server: nginx/1.0.14 Date: Mon, 13 Aug 2012 18:13:44 GMT Content-Type: text/html; charset=utf-8 Status: 401 Unauthorized WWW-Authenticate: Basic realm="Application" X-UA-Compatible: IE=Edge,chrome=1 X-Runtime: 0.099212 X-Rev: 9301db5 X-Host: web3 HTTP Basic: Access denied.
I think it’s trying to say that your application isn’t allowed to request a new access token whilst one is already valid.
Refreshing the Access Token
In a successful exchange of authorisation code for access token, you should see a response like this.
In OAuth, The
expires_in value should be the time in seconds that the access token is valid.
RECOMMENDED. The lifetime in seconds of the access token. For example, the value “3600” denotes that the access token will expire in one hour from the time the response was generated. If omitted, the authorization server SHOULD provide the expiration time via other means or document the default value.
604800 which is consistent with their documentation as it works out as 7 days. As this countdown starts when you exchange the tokens, I convert the number into a concrete date when I get the response. That way, I can see later if I actually need to refresh the token. However, it seems that you can refresh your token at any point.
The process is similar to the requesting the original access token. Make a Basic auth HTTP POST but with a slightly smaller body.
POST /v2/token_endpoint HTTP/1.1 Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ= Accept: application/json Content-Type: application/x-www-form-urlencoded User-Agent: Java/1.6.0_33 Host: api.freeagent.com Connection: close Content-Length: 127 grant_type=refresh_token&refresh_token=12wXjd7SL7SLOE1sdsaX8oCgix
which will return something like