Generating Signed Access Tokens (HMAC)
Generating Signed Access Tokens
Building simple access tokens a very common task when building an API. It is also a good topic for an interview question. In addition to a general authentication token, you may need to generate any number of other tokens including tokens for password resets, email verifications or api keys. A very interesting kind of access token is on that stores data that signed with a secret key. This actually allows you pass around data that cannot be tampered with and it keeps you from having to store the token in the database.
Hash Based Message Authentication
What I have just described above is actually something called HMAC - hash message authentication code. It is a very simple algorithm which we will implement below.
How Does It Work?
In simple terms you have a secret key that you store on your server, some data that you want to build into the token and a signature created from these parts. Later, you will decode the data and signature and try to rebuild the token from these parts with your secret key. If it matches, your access token is valid. The coolest thing is that you can store an expiration time, a user id, an email - basically any piece of extra data on your token. Again, all of this is achieved securely without any database required.
THE SECRET KEY
It can be as simple as a random string in a config file like so:
var secret = 'skKaTT2dJRXSH3sMxkZ2aWY95jfTeX';
Making it very very long is pointless because any HMAC algorithm will shorten it to a specific length.
BUILDING THE TOKEN DATA
In this example, we are going to build the body as a JSON object, stringify it, and encode it as base64. This way it should be safe to pass as a URL parameter if need be.
BUILDING THE SIGNATURE
This is the root the work - the HMAC algorithm. It is essentially a function that takes 3 arguments: the key, the data, and the hashing algorithm you will use. There actually a ton of very nice javascript implementations here. And if you read the article it states that it is sufficient to do something like var sig = sha1(key + sha1(key + message)) and the key padding is not critical to security. Needless to say, we will not re-implement HMAC to RFC spec mainly because it is a bit of a pain to do with browser-based javascript.
TESTING IT OUT
Here is a jsbin where you can see the HMAC system in action. We generate a signed token that stores some information and then later we are able to parse the information back out of the token. In this way you can create that tokens that have expiration dates and pass other information all without using a database. Make sure not to store any secret information on the message as it is still visible, just not possible to tamper with!
Full code, copy of what is on jsbin
Here is a copy of the HTML + JS that you need to see this working, in case the JSBin link did not work for whatver reason