Question

I'm using OAuth 2.0 with Laravel (Passport) in order to grant access to my frontend app to the API. Access tokens generated this expires after a while.

Now, I have a second app that has to consume the same API but sessions in this app must not expire. I need to get tokens with no expiration for this app. Right now, I implemented a workaround consisting of a personal access token with a 10 years life span. However, what I would like to get is a long-living token from the OAuth service.

The problem with the workaround is that I get a new personal access token whenever I log in, but the long-living one still remains alive. I'm afraid of anybody stealing me the token and getting access to my API indefinitely, so saving the long-living access token in my front-end app isn't an option.

Was it helpful?

Solution

About long-lived tokens

In a nutshell, don't implement long-lived tokens. You are right to worry about token steals and the difficulty of identifying whether these tokens have been really stolen or not (tokens are terrible at identifying real persons unequivocally). Not to mention the potential data leakage caused by attackers impersonating tokens' owners.

Generally, access tokens on the client-side are a sensible vector of attack. Token steal is one vector, Cross Site Scripting is another good one.

Short-lived tokens are not safer per se tho. They are exposed to the very same threats. The idea of short-lived access tokens is to reduce the window of time for these "sensible vectors of attack" to happen.

You mentioned Facebook as an example, but, What do you know about Facebook's access tokens? Facebook's access tokens expire too.

Also keep in mind that the access tokens that are generated in browsers generally have a lifetime of only a couple of hours and are automatically refreshed by the JavaScript SDK

developers.facebook.com

Reality vs perception

Expiring or not, you can "simulate" a long-living session scheduling token refreshments. The process can take place continuously (every X mins, hours, whatever) or frequently (daily, weekly, monthly) or, the one I prefer, when the token expires.

The latest is easy to implement. It takes us to handle 401 HTTP responses whenever they happen (without worrying about the reason). If any connection ends with 401, we force the token refresh and retry the previous request. The cycle can take place automatically in the background without involving the user of the app. Until a new login is required.

If the cycle fails, it's pointless keep trying so, we delete all the tokens in the client side and we redirect the application' state to the login, restarting the authorization cycle.

Note: Remember that refresh tokens are even more critical than access tokens (for obvious reasons), so be very careful with its storage.

One API, multiple clients

Consider treating each app as a different client of the API and provide them with different "client_id" and "secret". This way, each client gets its own access token, allowing us to set different life spans for every token. For example, the 2nd APP can obtain tokens with a longer life span than those provided to the 1st app.

OTHER TIPS

You should not do this.

Give your other app a username/password and allow it to sign in, get refresh tokens etc as a service user

Licensed under: CC-BY-SA with attribution
scroll top