Library to generate API keys?

We want to secure our REST APIs by handing out API keys to our users. Some of these API keys should have an expiration time-point, while others not.

So far, we’ve be using the token library. But its approach has a significant drawback: if you change the expiration time (for new keys) later, all existing (older) keys become invalid.

I searched for alternatives, but the best I could find are JSON webtokens. However, these tokens tend to get pretty long, which makes it difficult to copy & paste them (even if they only encode a small payload and an expiration date).

Does anybody know an alternative that has lesser characters?

(I could create my own hashes and store them in the database, but that means that the database has to be checked every time the token should be validated. I would prefer a token that has an inherent expiration time (but only if required), so the server can directly decide if it is still valid or not. That’s the beauty of both token and jsonwebtoken.)

Random.id(#)

1 Like

You could store the hashes in redis instead of mongodb. Redis is created to perform high performance lookups. The TTL for each entry would be the respective API key’s expiration time, so you would be free to assign different values at will, and changing an expiration time would be equally easy.

If you don’t find the API key in redis, it either never existed, or it was automatically deleted when the TTL expired.

If the key exists, you could still check how much time is left until expiration, and, if your API supports that, you could also issue a warning in the response so that the client can take action to renew the token (or get a new one etc.)

A “copy” button can easily help this UX concern

More thoughts. If it’s inconvenient for you to use redis, here’s another idea: you could use the crypto module in Node.js.

The aes-128 could be just enough for this use case (I guess), but if it isn’t, you can use any supported algorithm of your liking. Your unencrypted API key could be a stringified JSON tuple of the userId and expiration date (e.g. UTC date or unix ts), with the latter being omitted for no expiration.

For this symmetrical algorithm you need a secret password of 16 characters.

If you can’t decrypt the provided API key with your secret password, the key is invalid. Very simple.

E.g. the algo aes-128 creates from the payload blah and from the password passpasspasspass the encrypted output 8CNZdDrXucdSp84Qb4gBpQ== which is very conveniently short. Using the very same crypto package you can decipher it to get back the initial payload of blah. Try this online here.

If you’re not familiar with it, here’s a neat and simple tutorial of the Node.js crypto module.

This would be it, with just a couple lines of code. The drawback is that once an API key is generated, you can’t change its expiration date (whereas with the redis solution you could).

1 Like

Random.id doesn’t work here, since it won’t allow me to store an expiration date.

Sounds like a good approach, thanks! I don’t need to update the expiration date of a particular API key after it has been issued, I only want to be able to set different expiration dates to new ones (which token won’t support without invalidating the older ones).

1 Like

Well, as they say, appetite comes with eating :slight_smile:

1 Like