- Access and Refresh Tokens are JWT bearer tokens
- AT expires in 5 mins
- RT expires in 3 months
- Auth Service provides token rotation for other services
- Auth Service keeps track of Refresh Tokens and stores them in the database
- In production Auth Service shouldn't have access to users data. This issue can be resolved by providing to the Auth Service appropriate endpoints from user microservice. Here however AS manages user data as well.
- For convenience AT and RT are being sent as json object. Advantage of sending data in headers is that it can be accessed before the body is downloaded, so there's a place for a performance improvement.
-
/login - SPA => Auth Service
- POST, requires username && password sent in body
- return AT & RT pair
-
/refresh - Resource Server => Auth Service
- POST, AT && RT sent in body
- return new AT && RT pair
-
/verify - Resource Server => Auth Service
- POST, AT sent in body
- return boolean
- Stores Refresh Tokens
- Columns
- id
- tokenstr - token in string form
- rootId - id of root token used to invalidate a family of tokens
- refreshed - set to True upon token rotation
- Improvements
- tokens expire after 90 days, so whole tokens families could be deleted automatically
- SPA makes a request to Auth Server's /login endpoint
- If login & password combinaction is correct
- AS responses with jwt access & refresh token pair
- AS stores RT in database on AS side. DB can't be accessed by ohter services.
- SPA stores AT + RT in secure storage
- Otherwise user is asked to input correct login data.
- SPA asks Resource Server for sensitive data
- Access Token is being sent as part of a request (header or body, pros and cons are described in Details section above)
- Resource Server makes a request to Auth Server's /verify endpoint
- AS verifies token and sends response
- If token is valid
- RS responds to SPA with a protected resource
- Otherwise RS tries to refresh token
- Resource Server makes a request to Auth Server's /refresh endpoint (expired AT & valid RT)
- AS validates both
- If validation passes RS responds with new AT & RT pair
- Resource Server makes a request to Auth Server's /refresh endpoint with expired token pair
- AS responds with 401 unauthorized
- RS redirects SPA to login screen
- Malicious user steals Refresh Token from User
- User continues using SPA
- RS refreshes AT & RT pair
- User goes offline
- Malicious user tries to use stolen RT
- AS keeps track of previously used tokens and invalidates stolen token and Users newest token.
- User comes back online
- User has to log in again due to security breach
From auth0 article:
"Refresh token rotation guarantees that every time an application exchanges a refresh token to get a new access token, a new refresh token is also returned. Therefore, you no longer have a long-lived refresh token that could provide illegitimate access to resources if it ever becomes compromised. The threat of illegitimate access is reduced as refresh tokens are continually exchanged and invalidated."
"It's critical for the most recently-issued refresh token to get immediately invalidated when a previously-used refresh token is sent to the authorization server. This prevents any refresh tokens in the same token family from being used to get new access tokens."
python -m venv .venv
pip install -r requirements.txt
flask --app flaskr --debug run
This repo is just a proof of concept and it's not meant to be run in a production 💀