When to refresh expired Firebase3 (Web) Token for API request - javascript

I'm currently using firebase.auth().createUserWithEmailAndPassword(email, password) to authenticate users and using the JWT token from firebase.auth().currentUser.getToken(true) for API requests. However, Firebase is invalidating the token after 1 hour. So I'm wondering how should I refresh the token. Do I have to use my own custom token generation to properly utilize token refreshing?
I'm currently using this though I only tested it once but it seems to work.
firebase.auth().onAuthStateChanged(function () { // Refresh token here })
I've been reading the docs over and over again and haven't seen any mentions of refreshing the tokens for the Web Apps. I've also looked at example repositories for firebase and have not seen anyone use onAuthStateChanged for something like this. So I'm wondering is this the right approach for client side token refresh? The reason why I feel this might not be the best approach is because this might have a race condition. For example if the token expires and I send an API request with the old token before I refresh the token then my API request will have an auth failure for token expiration.
This is very similar to the question in Firebase DB HTTP API Auth: When and how to refresh JWT token? but slightly different in the sense that the question is for using Python and no mentions of onAuthStateChanged.
Thanks!

For those who came into this post looking for an answer. You can grab the token right before all your API calls to get the token.
// Make sure you don't pass in true which will always refresh the token
firebase.auth().currentUser.getToken()
Firebase will internally determine if the token needs to be refreshed or grab from cache. If you notice Firebase will not send any network requests until the token is expired.

Related

How to handle expired user ID token in firebase?

I am using Firebase authentication to authenticate users. Whenever, the user is logged in, I get the user's ID token with user.getIdToken(true) and set it on the local storage. With that token in the authorization header, I am requesting my back-end API.
On the back-end side, I am using Firebase admin SDK to authenticate the request and the user with the client-side ID token passed in the request authorization header.
This works for a while. But after some time I get error:
ExpiredIdTokenError: Token expired, 1620908095 < 1620915515
I saw that Firebase refreshes the ID token on its own. But I don't think that's the case. I have looked through the developer tools network tab, and there's also an observer method to check whenever the token has changed => onIdTokenChanged(), but the token is never refreshed.
I couldn't find any information on the Firebase docs either, and I was hoping if you could help me:
How can I generate a token without expiration limit to last until signed out or at least for some more time (1 week maybe)?
If I cannot the set the expiry limit of the token, what steps should I take so that I can send a valid unexpired token when I am request data from my back-end? Do I have to call user.getIdToken(true) every-time and get a fresh token before I request from my back-end API?
The idTokenChanged() observer is a bit misleading. It will fire when the token is refreshed, but the token is only refreshed automatically when you also use other Firebase products (like its database or file storage). In other cases, as you said you should call user.getIdToken(), which will refresh an expired token for you if necessary, everytime you call your API. You don't need to pass true into this method unless you want to have a completely fresh token everytime (which you most likely don't need).
To my knowledge you cannot control the expiration of tokens generated with the client SDK, for that you would need to generate your own tokens on the server.

Are access tokens made redundant by refresh tokens?

I'm new to webdev and have implemented access token & refresh token based authentication in my express project. However, the more I look over the implementation I'm starting to question why access tokens exist when it appears that refresh tokens make them redundant. Perhaps it's just my implementation.
For any task that needs authentication, I send off a cookie with both an access token and refresh token to an auth server. It looks at the access token, and if it is both valid and unexpired, it will send a 200 back and allow any express middleware to continue on.
However if it has expired, it will then query a database to see if a matching refresh token exists and, if so, will send a new access token.
As the lifetime of the access token decreases, the auth server will need to do more database searches to verify the refresh token. At that rate, why bother with the access token and instead why not rely solely on the refresh token? After all, the refresh token can be removed from the database and the authorisation server can reject any requests made with it.
The only reason I can think of the access tokens existing is to reduce how often a page will need to query a database, but that seems too simple. Since I'm fairly new to this, I know I must be missing some larger concept. Can anyone enlighten me?

Should the Firebase Admin SDK or Client handle token refresh?

I am attempting to use firebase on my server for authentication and to provide an authentication experience for users that does not require pulling in firebase client side (for the moment).
A /login endpoint receives a username and password. Using firebase.auth().signInWithEmailAndPassword, I am then returning the JWT token to the user. They can then use that in subsequent requests to my RESTful API as the bearer token.
The problem I'm struggling with is when that token expires (after an hour). Part of my flow when a request comes in that requires auth validation is verifying the token with admin.auth().verifyIdToken, and rejecting the request if it's no longer valid.
Is it correct to:
(1) provide the client with the refresh token as well in the initial sign-in so they can handle the rejection and then request a new JWT token?
(2) perform some action on the admin SDK to refresh the token on the user's behalf
In typical oauth scenarios I've worked with before, the client has always been responsible for refreshing the token, however I can't for the life of me figure out how to retrieve a new JWT token from that refresh token using either the admin SDK or the firebase SDK
I don't know if the firebase SDK that usually resides client side is handling this token refresh behind the scenes whenever it is used with firebase.database, etc. If i'm not using that client SDK, but instead using the token as a bearer token, can I have the client pass the refresh token for exchange of a new JWT token from the backend?
It's likely staring me right in the face, I'm just not seeing it.
The Firebase Authentication SDKs keep the refresh token in the client-side code, together with the ID token, and then use the former to mint a new ID token when needed (about 5 minutes before the current one expires).

How to handle JWT token expiry in react native and redux app

I am fairly new to implementing JWT. I had a few questions while implementing JWT. I am using axios to make requests.
When the user logs in or registers. I get an accessToken, which expires in a few days. I dont have a refreshToken because I think the backend is built on django rest framework.
Now if I get a status code of 401 in a request, I try to check if the token has expired and if yes, then refresh the accessToken, but at times even the refresh token api returns 400 suggesting that this token is also expired, at which point I need the user to log out.
I think this is a bad User Experience, Why is that we cannot refresh the token using old token. Is there a way to keep it from expiring? Can anyone point me to an example which solves the following problem with a correct implementation of axios interceptors?
Since you are using Django rest framework, consider using Djoser with JWT tokens, then djoser sends you access and refresh tokens from the backend. Once the backend preparation is over, follow this simple article to refresh and access tokens automatically from react native. Hope it helps you.
You can create a token which will never expire but that's a bad idea for security reasons. If the token is stolen then someone can always access the user's data. You can set the expiration date in exp claim. Read more here: https://gist.github.com/soulmachine/b368ce7292ddd7f91c15accccc02b8df

How to hide my JWT token On Javascript Ajax API Call from Frontend?

My Question is that I was Implemented JWT Token When User is logged In. Also Done some test Through POSTMAN. Getting token when User is validating with username and password. Now My API is completed and whenever Front-end Guy needs API Calls, He have to pass JWT token. Now This token is visible on AJAX API call. Is there any way that I can Hide all token so that Attacker won't get this token?
jwt is not secured by default.
first if you want to work with jwt in your website,it must work on https.
second if you store it on a cookie use the cookie http only option to prevent javascript cookie hijack
also you can use jwt in OAuth for more features

Categories

Resources