Firebase Cloud Messaging (WebPush) token expiration handling - firebase

As I found out in Firebase source, every token has an expiration time of one week. And because messaging().onTokenRefresh is not implemented now, I'm assuming that there is no way of sending webpush-notifications to users that haven't been on my website with configured FCM for a week or longer.
Or my assumption is incorrect and this expiration exists only on browser side? And tokens on the server-side of FCM aren't expiring without a call from browser to recreate token?

It's not an actual expiration, but just a way to update the token information on Firebase servers. If the token is still valid (and it most likely is), updateToken method will return the same token, and it will keep working.
If you get a different token after a getToken call, you can safely overwrite the previous token in your server.

Related

AWS Cognito expired access token

In my application I have used aws cognito with next auth for user auth.
In the jwt callback that I have from api next-auth I receive an access token, which is then saved and sent to the client side. There, I save it in local storage and, among other things, I send it to my api which checks if it is correct.
The problem is that after an hour the access token expires and does not get a new one (always next-auth gives me old value). Has anyone had a similar flow and knows how to manage a session refresh? I will add that I am not automatically logged out because next-auth is managing it underneath, but it does not return the value of the new access token to me.
Do you have any ways how to manage this?
I can suggest a workaround that would take the least effort to solve this quickly. Amazon Cognito contains 3 kinds of tokens, the ID Token, Access Token and Refresh Token.
From the Amazon Cognito console, you can increase the validity of the token you're dealing with from there. A good idea is to refer to this answer.
Albeit you might need a couple of methods to assert security and robustness.

Firebase Auth Token Persistence Security Risks

Current Setup
I'm using cloud functions and the admin sdk for my backend. The front-end is a combination of React, Firebase Auth (web sdk), and redux firebase for authentication. Currently, I force a token refresh for each request for specific components of my react app and save the token to local storage.
Reasoning
Initially, I thought I could simply listen for the auth state to change in my front-end's index.js and then refresh the token accordingly i.e. firebase.auth().onAuthStateChanged A few processes on my app can take quite a while (i.e. uploading content) and I've noticed the change of auth state doesn't get triggered anytime outside of the initial login or a logout.
For example, the user begins to upload content 1 minute before the token is set to expire. The final API requests following the uploading then fail because they finish after the token has expired. The token doesn't get updated and requests fail to my backend as 403 unauthorized. The solution was to use currentUser.getIdToken(true) upon the first load of each of these components. Therefore ensuring a new token is always available.
Problem
Are there security risks to this approach? If yes, how can I mitigate them or is there a better approach to persist the token? I'm nervous about giving users the ability to indefinitely refresh their tokens.
is there a better approach to persist the token?
You're supposed to use onIdTokenChanged to listen to changes in the user's ID token as it changes over time. It works like onAuthStateChanged, except you get fed ID tokens. It's updated automatically as needed by the client SDK. You can store the latest token for use in your calls without having to fetch one with an API call each time.
Are there security risks to this approach?
Not really. Refreshing an ID token is necessary, and the Auth SDK does it automatically internally anyway.

FCM Token - When should I store/save it on my DB?

I am not sure what a proper FCM token handling mechanism would be so Iโ€™m writing our process down here just to get some validation or suggestions for improvements:
Fetch FCM token on client Login (Flutter)
Save FCM token on our Database (Using our REST API)
Delete FCM token on Logout (Using our REST API)
Q1: Should we be getting the FCM token more often than just on login? AFAIK, FCM token only changes on app re-installs, clearing cache, etc. Does this also include app-updates from the PlayStore? In that case, should we save the FCM token on every app launch since the user will remain logged in after an app update and hence we wouldn't trigger the save FCM call.
Q2: Did I mention the right way to handle deleting FCM tokens from our DB? We donโ€™t want the user to keep getting notifications once they have logged out.
Q3: An add-on idea is to send the device_id to the server along with the fcm_token so that server deletes all previously saved FCM tokens for that device_id. This is useful to not have useless tokens on the DB from cases where the user uninstalls the app without logging out (which means that the DELETE fcm_token call never went through.)
The FCM token is refreshed under conditions that you don't control, and those conditions have even changed over time. To handle token updates properly, you'll need to implement both initially getting the token and then monitoring for token updates.
Note that FCM tokens are not associated with a user. It is fine if you want to associate them with a user, but it's up to your application code in that case to maintain the association. So that for example includes deleting the token from your database when the user signs out, as you're doing in step 3. ๐Ÿ‘
For keeping your token registry clean, you can indeed do this proactively as you intend, or reactively as shown here: https://github.com/firebase/functions-samples/blob/master/fcm-notifications/functions/index.js#L76-L88
Hi Rohan fundamentaly you should use below logic to save tokens on server.
Step1:
as soon as you get token in callback whether new or same try to save it localstorage.
Step2:
Call your REST API to save it to your server. it is upto you if you want to send unique user identifier along with the token.
Step3:
It is obvious you will recieve token callback a lot of time so you can check whether you have similar token in localstorage, it means you have the token on the server so no point calling REST API.
Step 4: Now your app can send events back to server and based on it trigger Push notifications to the users.
Step 5: You can Add/update user token based on uniqye user identifier. In some cases a user can be guest user, so your app should generate guest userId and link it with token.
Stay safe.

Using firebase jwt to authenticate users to external server\service?

Okay so in my iOS app I log the user into firebase, then get the jwt token. So now I have my server with an api which accepts an idtoken in the header of the GET.
What do I do here? Certainly I wouldn't be validating the JWT againt firebase on every single API call right? I mean its fast, but that adds latency with a second external check, no? How does one simply just decode that guy in C#? I have an Auth0 layer already and that decodes the JWT with my server-stored secret, but that same code doesn't work for the Firebase token.
Could it just be decoded then extract the user details from that, maybe just check expiry and if expiry > X months it's still okay?
In order to verify Firebase ID tokens and JWTs in general, you only make a network call on your server to get the public certs which are usually not updated for several hours. You could cache that and try to verify with an ID token and if it fails, only then, load the new public certs.
And yes, you must verify the ID token on each call especially since Firebase ID tokens expire after typically an hour and need to be refreshed continuously.

LinkedIn API: What determines the expiration time of an access token?

When pulling information from the LinkedIn API, the access token will randomly expired, and the application will not be able to pull the information from the API. This issue randomly occurs after an extended period of time. I am trying to determine whether this could possibly be coming from LinkedIn's side. Is there any way to verify?
According to the LinkedIn documentation, you should receive the expiration date of the access token in the same request you receive the token.
Access Token Response
A successful Access Token request will return a JSON object containing
the following fields:
access_token โ€” The access token for the user. This value must be kept secure, as per your agreement to the API Terms of Use.
expires_in โ€” The number of seconds remaining, from the time it was requested, before the token will expire. Currently, all access tokens are issued with a 60 day lifespan.
One thing to keep in mind is that access tokens can be manually revoked by the user:
Invalid Tokens
If you make an API call using an invalid token, you will receive a
"401 Unauthorized" response back from the server. A token could be
invalid and in need of regeneration because:
It has expired.
The user has revoked the permission they initially granted to your application.
You have changed the member permissions (scope) your application is requesting.
Since a predictable expiry time is not the only contributing factor to token invalidation, it is very important that you code your applications to properly handle an encounter with a 401 error by redirecting the user back to the start of the authorization workflow.
One thing that is not mentioned on this page, as #JustinKominar mentioned, is that only your most recent access token is valid. That means requesting a new access token will invalidate all of the previous ones, so make sure that your tokens are up to date!

Resources