Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check Access Token every Request with Redis

I'm currently implementing an OAuth 2.0 Architecture for my RESTful API.

With each request I set up an Authorization Bearer Token in the HTTP Header for all my clients to make Authorized Requests.

Authorization: Bearer sdflksd3r4823vkn95-03850432 

I understand that it's common practice to just accept the token in the API until the expiration date. But say if a user wanted to revoke the token, I would need to employ a method of checking the status of the token with each request.

So I was thinking of going to the Db to check for every HTTP request. I have a feeling that this won't scale nicely due to performance reasons.

So I was wondering if a solution like Redis would be appropriate for very fast single reads of the access token status?

like image 210
Max Alexander Avatar asked Apr 27 '13 01:04

Max Alexander


2 Answers

The point of having an HMAC for a token is so that the server can verify it quickly without calling out to any external data store (eg Redis, MySQL, etc). This has the added benefit of scaling out nicely to multiple server since there is no shared state (all info to verify the token is the token itself and the key for the HMAC).

If you're going to have a blacklist of revoked tokens then something like Redis would probably be fine (though still slower than not doing a remote call for each token verification). Setup properly, with low latency between your Redis instance and your API server(s), you'll should see <10ms per request.

Bonus: Another option to speed things up even further would be to use a Bloom filter to handle caching of rejected API requests. That way you only go to Redis if the Bloom filter flags the request token as possibly revoked. Note that since this is another layer of caching you'll have to update the state of the Bloom filter when a token is rejected.

like image 51
sehrope Avatar answered Sep 25 '22 00:09

sehrope


I'm making something similar for myself.
For token syntax and encryption, I suggest you to use JWT, it is a good standard for that.
It's ok using redis to store a pair token/userid, also because we can set an expire value.
Also I inserted a bloom filter in the middle, but I made it in the opposite way than sehrope suggestion: I'm storing all the tokens at login in by bloom filter, so if the token isn't present it is definitely invalid; else is probably correct but I have to make a check on Redis to be sure; but now I have a problem: if I want to scale up my auth system I need a stateful load balancer between auth servers. IMHO, using a bloom filter to create a blacklist isn't correct: if I blacklist in bloom filter the revoked and wrong tokens, if the item isn't blacklisted the bloom filter returns false (and I have to check it in redis backend to auth); else if an element is present (blacklisted) I have to check it on redis to be sure because bloom filter true response can be a false positive.

like image 43
Alberto Zuin Avatar answered Sep 25 '22 00:09

Alberto Zuin