Tuesday, 21 January 2014

Xero API .NET Client - Implementing your own ITokenRepository

We recently integrated our FoodStorm product with Xero, and we decided to use their .NET API. Most of it is pretty straightforward - except for dealing with access tokens in .NET as their documentation is lacking somewhat.

So here is a bit of a brain-dump of my experiences...

To perform any API operation, you need to first instantiate a Session. In our case we have Partner access, so we need to create a XeroApiPartnerSession. The constructor requires an ITokenRepository (it also requires Certificates - but that's for another blog post!).

So since you can't create an instance of an Interface, you need to create your own class that implements ITokenRepository, and inside that class it's up to you to deal with the loading & saving of access tokens.

When I first saw this, I thought it was overkill - why couldn't I just pass in my access token?!? But I delved more into the API I learned that access tokens expire after 30 minutes - even with Partner access. This means you need to Renew your access token periodically. The good news is that if you implement an ITokenRepository, all this complexity is fully handed by the .NET API, so it's a pretty good design after all.

So onto creating a Token Repository... The ITokenRepository interface looks like this:

As you can probably guess, you need to make the Get methods return your tokens, and your Set methods need to save the tokens. My initial idea was just to Serialize the AccessToken and RequestToken classes to a file - easy peasy - until I realised those classes weren't marked as Serializable...

So that meant I would need to store the values of the properties in the Set methods, and then re-create the classes in the Get methods. And that's what I did:

For simplicity sake, I decided to serialise all the required properties to my own JSON object, as I didn't see the need for specific DB columns etc - but that's up to you. However note that ALL of the properties I am save & loading here are required! If you miss any (which I initially did), things will not work correctly within the API.

Anthony.

2 comments:

Anonymous said...

Hi Ant,

Thanks for the post. I was wondering if you could shed some light on exactly how to create a new XeroApiPublicSession (or PartnerSession in your case) using the TokenRepository class.

My user has been through the Xero authentication and I have their Access Tokens saved to my database. Now on subsequent visits to my website I don't want them to be required to do the Xero authentication again, I want to use the saved Access Tokens from my database.

Could you help me in how do I go about doing that please if you have any examples?

How do I go about creating a new Repository by using the saved Access Tokens I already have?


Thanks in advance and again thanks for the initial post.

Mathew

Anthony said...

Matthew,

To create a session using your TokenRepository, the code is like this:

var session = new XeroApiPartnerSession(
"MyAppName",
"MyXeroConsumerKey",
signingCert,
sslCert,
new MyTokenRepository());

You'll notice that there is no "access token" parameter! Instead the session class will call the GetAccessToken method of the repository.

If you've saved your access token to your DB, then make the GetAccessToken method return the value from your DB.

A few other comments I'll make:

- Access tokens expire. If you're using Public API access, then your users will have no choice but to authenticate each time they want to communicate with Xero - this will issue you with new access tokens.

- Even if you upgrade to Partner access, the tokens will expire. However, internally within the token repository, there is a "renew access token" method which will automtically swap out the old token with a new one whenever required. This is where the SetAccessToken method comes into play - this method will be called whenever an access token is renewed, allowing you to save the new value to your DB.

But like I said, this is only for partner access and I imagine you'll get an unauthorized error if you attempt to renew a public access token.

Hope this helps.

Anthony.