I am not sure if this is doable for a web. Say if I use ueberauth or pow assent to connect with microsoft graph API. From microsoft doc, they mentioned that the access token given is only limited to 1 hour.
Provided I store the minimal user info in my database (along with access token/refresh token), is there anyway I can execute a http rest api command every 30 minutes in background to get new combination of access/refresh token?
Iâve published not long ago the OAuth2TokenManager library that does that.
Documentation is a bit sparse, what is not shown in the examples is that you have to register the refresh token first using OAuth2TokenManager.RefreshToken.register/5, with the "sub" field set if the token cannot be introspected.
Also the backend for storing tokens is based on ETS + DETS, you might want to implement your own (DBâŠ).
From what understand, after the client connect to my web app using pow assent/ueberauth, I have to register both ârefresh_tokenâ and âaccess_tokenâ using the OAuth2TokenManager library right?
Does the automated request for new âaccess_token/refresh_tokenâ is being handled as well, or need to be set from âelixir codeâ to invoke the library function? Because I believe most apps have different expiration duration and I am not sure how to do the automated part (when to invoke the function to get new token pairs)
To see what happens on the wire in dev, you can activate the Tesla Logger. Useful to check if the token is correctly introspected.
Yes, it checks if there is a valid access token for the given scopes using expiration time and requests a new one using the refresh token if thereâs none. It implies the access token was registered with an "expires_in" field or the access token was successfully introspected, in which case the "exp" is used to determine the access tokenâs end of validity. At least this is how it should work, if not, open a PR
Also note that they can be several valid access tokens for one refresh token. If you use scopes, the best practice, called the least-privilege principle, is to use access token with just the scopes you need - no more.
You still have to manually request a new access token when the API answers that the token is invalid. Could happen if the access token is revoked, the API has âlostâ it, etc. In this case the API should answer with a 401 or 403 error code following RFC6750: 3 - The WWW-Authenticate Response Header Field if it is OAuth2 compliant. Guess itâd be a good use-case for a Tesla middleware.
Considering those security recommendations, I wonder if itâs safe to store the refresh token in a dets table and the access token in a public ets?
I would consider a refresh token as a piece of sensitive data, but maybe Iâm overthinking it or being paranoid.
Regarding the original question, although I havenât really thought it through, wouldnât it be possible to launch a GenServer Under a dynamic supervisor when a user logs in, with the current access token and refresh token, send to self a refresh message every 30 minutes and stopping it when the user logs out? You would have to either store the pod somewhere or use some sort of registry and obviously follow the aforementioned recommandations for gen_servers with sensitive data.
Of course this would provide less features than @tangui âs library.
A refresh token is indeed sensitive. The ETS & DETS backends are mainly for testing purpose and quick prototyping. It can also be stored on an encrypted drive.
Note that sensitivity depends on the granted scopes. Read-only scopes might be less sensitive than write scopes (like writing on someoneâs wall on Facebook, Twitter, etc.).
That said, a refresh token can be granted for a long time (several weeks, months) or even indefinitely, so it often needs to be persisted.
In the OAuth2 standards, there are no requirements to delete a refresh token upon user logout. Actually, thereâs no relationship at all between tokens and user session. In the OpenID Connect standard (a superset of OAuth2), itâs quite unclear but the consensus from implementers is that the refresh token has to be deleted when the user logs out, except if the "offline_access" scope was requested with the other scopes.
True, I had OpenId in mind (since Iâm working with keycloak atm) and tend to think of âoffline_accessâ tokens to be different than mere refresh tokens (for the same reason).
Thanks for the correction.