Check Access Token every Request with Redis

16,314

Solution 1

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.

Solution 2

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.

Share:
16,314
Max Alexander
Author by

Max Alexander

CoFounder of Ditto. A CRDT based NoSQL database written in rust that can sync over wireless peer to peer or client server. Available for iOS, Android, Web, and Servers. Twitter: @mbalex99

Updated on June 16, 2022

Comments

  • Max Alexander
    Max Alexander almost 2 years

    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?

  • Max Alexander
    Max Alexander about 11 years
    I was definitely considering a bloom filter. Though I was also wondering if it using a singleton cache was a viable option
  • sehrope
    sehrope about 11 years
    If you only have a single server then you have a lot more options as you only have to maintain state in a single place. Having an external server like Redis maintain the state allows you to have multiple API servers. A singleton only works if you have a single server. Another alternative would be a distributed Map (Coherence, Hazelcast, etc). If the tokens have relatively short expirations then you could also remove then from the distributed map when they expire to reduce it's size.
  • Max Alexander
    Max Alexander about 11 years
    Excellent answers. Thanks a lot!
  • Max Alexander
    Max Alexander about 10 years
    I am actually using a JWT Token on my AngularJS site stored in sessionStorage.They will have to login every time the browser application is closed. This is also a 30 minute expiration time before a user will have to be reissued another token. I simply use redis to make a note of it, and it allows me to find tokens very quickly.