silviurosu

silviurosu

Protect API with token + history logging

I have some public API’s that I want to restrict with tokens. Basically I want to allow API calls only if the client has an active token. Each token will be restricted to a host or a list of hosts.
I am not sure about implementation though.
My thoughts are to have a Phoenix plug that will verify the token from header. Will search for token in database then will match the request host and will continue if everything is fine. Also I would like to log the request to be able to do graphs and statistics later.
My API though has a high request rate (tens per second or more). I do not want that the token validation to be a bottleneck though. Since I need to rely on database calls and regex matches I am not sure about the impact. Also I need to count each request in database after the call.

One optimisation would be to keep the token in memory for a while after loading it from DB, or to load all the tokens at the application start (This can lead to stale data though). Also I have a cluster of nodes and I want to rate limit for all together.

Did somebody encountered the same use-case? Can you share your thoughts if you have different ideas?

Most Liked

hauleth

hauleth

Not possible if you also want to provide token revocation. Sooner or later it will require the DB check. You can use signed tokens for preliminary elimination of obviously invalid tokens. Alternatively stateless tokens could be used if, and only if, the lifetime of such token would be very short (like half an hour).

chasers

chasers

Yep.

Want to give Logflare a try?

Cache them in ETS. Either prepopulate and bust the cache or TTL them. Cachex has a nice TTL feature. If you have lots of api keys with a highly variable rate a TTL may not be optimal as you still might get a lot of requests to the db if you have a lot of infrequent api key usage.

Use erlang’s counters. Persist to the db as needed.

If you’re not showing the rate limit data anywhere in your UI I would just have a per node rate limit and not deal with any of this. But…

I managed to get Phoenix Tracker working to send rate limit data around the cluster multiple times per second but I wouldn’t recommend that.

I need to play with this a bit more but probably persist your counters per node per api token. Or maybe use pubsub to pass around the data and cache it on each node for each node. Again, really only if you need to cluster totals for some reason, otherwise just do per node limits.

hauleth

hauleth

DB of the revoked tokens is IMHO much worse idea than DB of allowed tokens. The later gives us useful tools like allowing user to list all their current tokens, review last usage of them, etc. Guardian DB is a hack because JWT is terrible solution for sessions.

Where Next?

Popular in Questions Top

_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: <h1>Create Post</h1> <%= ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call t...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52341 488
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New

We're in Beta

About us Mission Statement