How to handle expired user ID token in firebase? - javascript

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.

Related

Oauth authentication in exchange online - correct way to get refresh token from web and use in webjobs

Microsoft started to turn of basic authorization for Exchange Online and we must move to modern one.
We chose auhtorization code flow. User process authorization, we get auth code in url send it to server and get access/refresh token. Unfortunately default refresh token lifetime for SPA is 24 hours. Thats problem because we want to use refresh token later (e.g. days, months) in webjobs/api.
Our scenario:
User process authorization, scope is mail.send offline_access
We get auth code and send it to server
Server use auth code to get tokens
Tokens are valid and saved to database
Several days ago we use refresh token to gen new access token but request ends with exception (24 hour lifetime exceeded)
Our requirements in nutshell: Users allow us to send mail. Server save tokens and use them later in webjobs, api etc.
Can someone give us advice what is the proper way to get refresh token for long term use?

What is the Refresh Token authorization procedure

I'm currently working on a project with expressjs. For user authorization I use JWT tokens but until now only access tokens, because I just don't understand them together with a real example. So can somebody explain to me what the steps are the authorization goes through when someone logs into his account.
f.E.:
Refresh and Access Tokens get generated
Token gets stored into database etc.
Thank you in advance and have a great day
User sends a POST request with login credentials
Server authenticates and if successful, returns a JWT (usually in a httpOnly cookie). Server does not store JWTs in a database. The whole point of JWT is that authentication state is stored by the bearer of it.
For subsequent requests to protected endpoints, client needs to attach JWT. Server should check if JWT is expired and whether it has been altered.
Extensions that you might want to think about:
How to refresh JWTs:
There are different refreshing patterns that can be used. For
example, you can check the expiry of the JWT every time that your
server receives a request. If JWT is expiring soon, issue a fresh
JWT.
How to maintain authentication state on client-side without having to log in every time you refresh the page
How to really log a user out:
If you set the expiry as 30 minutes and a user logs out at the 15th minute mark, that JWT can technically still be used to access protected endpoints for another 15 minutes.

Strategy to handle expairy of refresh token

I am making a react application and using JWT for authentication.
As soon as a user logs in I issue a access token and set a http only cookie named jwt and value is refresh token. As per some articles I have read online it is suggested that access token have a short validity and refresh token have a long validity, so I set validity of access token to be 1 day and refresh token to be 25 days, (numbers are not very relevant). Now as soon as refresh token expires The user is automatically logged out.
Now the app I am developing is a data entry dashboard and I do not want the user to suddenly logout after entering a lot of data even if that happens once a month, so I want to know the industry standard to manage this kind of situation
There is a way to update refresh token without login-password pair:
When a refresh token expires a client have to get a new token pair (access, refresh tokens).
The client sends its access AND refresh tokens and receives a new pair (just like when authenticating with username:password).
You should track expiry of refresh tokens to prevent their reuse.
It is as safe as your flow because when a client gets logged out it understands that someone else already used its refresh token once. So it has to authenticate using username:password and invalidate the last refresh token.
I found an article explaining this flow

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).

Categories

Resources