- React GraphQL JWT Authentication and silent Token Refresh setup.
- This repository is to help people new to react with setting up their authentication system.
- in this example I'm using separate graphql-end only because I didn't want to send refresh token cookie with each request, by setting the path property of cookie.
- this example only shows the frontend client setup (considering below safety points) and backend settings must be set considering the points below.
- this example used @apollo/client (GraphQL client), react-redux, redux-persist, @redux/toolkit, react-scripts (create-react-app), react-router-dom
https://hasura.io/blog/best-practices-of-using-jwt-with-graphql/
- To prevent data from being stolen:
- BACKEND - send request over https only
- BACKEND - set SECURE flag on cookie to only serve it over HTTPS
- To prevent XSS attacks:
- FRONTEND - tokens not to be stored in localstorage
- BACKEND - tokens can be stored in cookie with httponly
- To prevent csrf attacks:
- BACKEND - tokens can be stored in cookie with samesite=strict or samesite=lax
- For phone app support:
- FRONTEND - save tokens in app state and send in request header instead of from cookie
- To support multiple open tabs at once:
- BACKEND - save refresh token in cookie for computer browsers with flags above
- FRONTEND - for phone apps save refresh token also in the app state and send in request header
- BACKEND - thus, backend must be able to read refresh token from both header and cookie
- BACKEND - use long running refresh token saved on database for revocation purpose. it's more secure since without database old unexpired refresh token can still be valid.
- To prevent sending refresh token with every request:
- BACKEND - set path flag on the cookie pointing to refresh url (https://stackoverflow.com/questions/57650692/where-to-store-the-refresh-token-on-the-client)
- BACKEND - since no session or db to record invalid JWT tokens set access token expiry time short and refresh tokens too
- FRONTEND - make sure not to persist the tokens with app state persisting
- FRONTEND - make sure to remove tokens from cookie and app state upon logout and
- BACKEND - configure CORS properly
- BACKEND - configure backend JWT settings properly
- configure clickjacking prevention
Note that the new SameSite cookie spec which is getting increased support in most browsers will make Cookie based approaches safe from CSRF attacks. It might not be a solution if your Auth and API servers are hosted on different domains, but it should work really well otherwise!