DEV Community

Cover image for React Query - Authentication Flow

React Query - Authentication Flow

Luca Del Puppo on April 12, 2023

Every application should handle an authentication flow; in this article, you'll learn how to build an authentication flow in your React Application...
Collapse
 
bartoszkrawczyk2 profile image
Bartosz Krawczyk

Never save your access token in localStorage. This is potential security vulnerability!. Use HttpOnly cookie instead.

localStorage can be accessed by any script running on your website. Any 3rd party code, like analytics for example, can steal your user's access token from localStorage. HttpOnly cookie can be set only via server's response and it can't be accessed via javascript, but will be send back to the server with http requests like fetch. So your server can read back an access token, but no external scripts can read it.

If you can't use cookies don't store your access token at all. Just keep it in your state. To avoid entering password every time user is refreshing/opening in new tab you can implement and store id token client-side, but fetch new access token from API every time. But then... It's better to just use any OAuth library.

Collapse
 
puppo profile image
Luca Del Puppo

Yes, I know. But for this demo I think it is a good enough the token in the localstorage. It is not the best solution but for giving an idea of how you can create an authentication flow with react query is okay.

I know and I understand your point of view, and also I agree with you but probably for this example it is too much.

But I appreciate your comment that helps people to understanding the problem πŸ™Œ

Collapse
 
kazumasadakane profile image
KazumaSadakane

HttpOnly cookie is also not safe. If you use localStorage to store a token, you should make the token short life time and also use black list.

Collapse
 
myguelangello profile image
Myguel Angello • Edited

So, do you believe that the most appropriate option would be to use cookies and JWT tokens with expiration dates and everything? @bartoszkrawczyk2

I always have this question about the most appropriate way to store tokens, an opinion from someone with more experience would be nice

Collapse
 
bartoszkrawczyk2 profile image
Bartosz Krawczyk • Edited

@myguelangello I am no expert, but two approaches I've seen in production apps:

  1. Don't do it client side. Let your API handle 3rd party tokens or OAuth flow and use HttpOnly cookie for browser-server communication. This is approach used in passport.js, Auth.js, Lucia Auth and all popular auth libraries. Lucia for example stores JWT tokens in DB and issues a HttpOnly cookie for your front-end app.

  2. If you need to do JWT based auth client side (again, not recommended, but sometimes necessary), store only id_token in localStorage and keep auth_token in your app state, private variable etc. When token is lost (eg. page refresh) redirect again to your OAuth provider. If your session is still valid you will be redirected back to your app, if not user will see log in screen. I am not sure how safe is this approach.

Most important - don't roll out your own auth. Use auth solution provided by your backend framework. Many frameworks (Laravel for example) have good authentication flow built in. If your framework doesn't provide any auth solution use something well known and documented (eg. passport.js for express app).

Collapse
 
sohanurrahman0 profile image
Sohanur Rahman

How can I handle httpOnly cookie if android/ios application consumes the api?

Collapse
 
tiagosatur profile image
Tiago Satur

There are many ways, one I've used successfully is JSON Web Token (or JWT) where we defined a expiration date of few days (the requests used a refresh token util then and after the token became invalid, so user should re-login). But there are alternatives like OAuth, biometric auth, Single sign-on...

Collapse
 
thomasluuu profile image
ThomasLuuu

To handle cookie for android/ios, it's easier for you to use SecureStore from expo to store cookie.

Collapse
 
bartoszkrawczyk2 profile image
Bartosz Krawczyk

@sohanurrahman0 Sorry, I don't have any experience with mobile authentication, but AFAIK OAuth flow (with separate id token and access token) is more commonly used on mobile.

Collapse
 
seancassiere profile image
Sean Cassiere

It's good to have more articles showing how great react-query is, and how something which pretty much all used apps, like authentication, is being showcased here.
My only critique would be to reduce the use of generics (and explicit typing in general), by simply type-casting the API calls, and letting the library's TS inference takeover for what the Fn is and it's variables.
Essentially reducing the verbose nature of defining these custom hooks.

Collapse
 
puppo profile image
Luca Del Puppo

It’s not so explicit but here there is a way to do that πŸ™‚ the post doesn’t show the integration with react but it’s a good starting point πŸ™‚
dev.to/this-is-learning/validate-y...

Collapse
 
tiagosatur profile image
Tiago Satur

Very useful example!

Collapse
 
puppo profile image
Luca Del Puppo

Thanks Tiago! I’m glad you enjoy it πŸ™Œ

Collapse
 
jwilliams profile image
Jessica williams

Very useful example keep going.