I'm using firebase 9.x with custom authentication. According to the documentation the token expiry cannot be more than one hour. Is there a listener which I can register to that will be called when the token expires.
The documentation also talks about automatic refreshing of tokens. I believe that is not applicable for custom authentication. Let me know otherwise.
https://firebase.google.com/docs/auth/server#use_the_firebase_server_sdk
Ideally the documentation (above) should have the requested information.
Thanks in advance.
The token that is generated server side (custom auth) is a JWT (JSON Web Token). This token must be supplied by your client (Android?) to the Firebase server to authenticate the user to Firebase. In the 9.x libraries, it seems these tokens now have a maximum life of an hour (i.e they are no longer accepted after 60 mins). (See Sam Stern's comment in this issue: https://github.com/firebase/quickstart-android/issues/31).
Sam indicates that once authentication has occurred using a custom generated token, the Android client will remain authorised until signed out.
If you actually require to know when your JWT token is valid until, it should be 60 minutes after you generate it on your server. If the token has not yet been used for auth with Firebase, at this point you could regenerate a new one and use that instead.
The documentation is misleading. It should say you have 1 hour to use the custom token to sign in. I also feel if the token is that temporary, then it should be single use. Otherwise it is confusing how they want you to use the token.
The SDK will take care of keeping the sessions tokens up to date IF YOU ARE SETUP correctly. For more info The custom tokens are only used to start a SESSION. So you have to have hour to use a custom token to SIGN IN. Once you are signed in and your Firebase Admin account and app configuration is setup correctly, the SDK can communicate back and forth with the Firebase back-end to keep the tokens up to date. Once you sign out with FirebaseAuth.signout(), you will need a new custom token to sign back in if it has been over 1 hour.
So in most cases, you really do not need to listen for token expiration
have you tried AuthListener?
mAuthListener = new FirebaseAuth.AuthStateListener(){
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
user.getCurrentUser().getToken(true);
// ...
}
};;
mAuth.addAuthStateListener(mAuthListener);
Related
background of this question
I'm using firebase auth for user authentication on my app.
I realized that firebase doesn't have a log of user information changes, so I can't answer user questions about it.
So, I'm planning to move the feature of changing user account info (like email, display name, and password) from using the client-side firebase auth library to using server-side firebase auth SDK for the purpose of taking logs of these changes to use for user support. Also, I'd like to make logout a user who changes account info.
I've looked for the appropriate API on the document firebase.google.com/go/v4/auth and found UpdateUser function. The struct UserToUpdate which is a parameter of UpdateUser can set a new email address, new password and new display name, but I can't find to set the parameter to make a user logout.
my question
Is there a way to log out a specific user by firebase auth go SDK?
Firebase Authentication's client-side sign-in is based on ID tokens, which are valid until their built-in expiration (by default: an hour after they are minted). Since no server keeps a list of all the ID tokens it has minted, there is no way to mark a token as invalid on such a list either.
The common approach to revoke access for a user is to:
Revoke the refresh token, so that they can no longer mint new ID tokens with it.
Add the ID token(s) of the user to a self-managed list of revoked ID tokens.
Detect the presence of an ID token in this list from your server-side code and security rules.
Optionally detect the refresh token revocation on the client
Instead of logging the user out, you can also force-refresh their ID token/profile on the client to get the latest information from the server.
I am new to firebase.
I don't understand how I can keep the users of my firebase app logged in when the max expiration time of an auth token in 1 hour.
I could use a function that uses the refresh token every hour but what do I do if the users phone isn't charged?
Thank you very much for any help.
A Firebase user's access token (or ID token) has a lifetime of an hour. After signing in the user, Firebase issues a refresh token that is used to get new access tokens if that refresh token is still valid and hasn't been revoked. If you are using the Firebase Client SDKs, they will handle getting new ID tokens as needed for you. Refer to the ID tokens documentation for more information.
An ID token essentially states "within the last hour, I have confirmed that I am this user".
If you are making use of Custom Authentication tokens from an Admin SDK, the token you give out to the caller also expires in an hour, but should be exchanged for a refresh token before it expires. Like described above, this new refresh token is used to request new ID tokens as they expire.
Firebase uses multiple token types to manage the authentication state of the user. The shortest lived of these (known as the ID token) expires an hour after it was created, but all Firebase SDKs actually automatically refresh that ID token before it expires.
This is handled for you behind the scenes, so in practice you shouldn't have to worry about token expiration - and your code can just get the currently signed in user everywhere it needs.
I have a web application where users can sign in with Google.
To the sign-in process, I add a scope to be able to access Google Calendar.
Now that the user is signed in, I would like to - in server-side - get their current Google access token in order to make a request and get a list of their events.
Is there a way to get the current OAuth token (no need for refresh token) in order for me to make this completely on the server-side?
I'd say that you can check this article and put special attention to the recommendation for websites.
I understand you have configured already the consent screen, which is the first step of the basic steps on using OAuth 2.0. So I understand that you only have to perform the following steps:
Obtain an access token from the Google Authorization Server
Examine scopes of access granted by the user.
Send the access token to an API
I think you can also give a look to this other doc for more GCP insights over your goal to authorize the request using user tokens
Edited:
Regarding the Firebase Authentication, I understand this happens at the user's device, and you could use some code to retrieve the token and then send it to your back end servers as mentioned in here.
As a sample here there's the sample code for retrieving the token in Android:
FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();
mUser.getIdToken(true)
.addOnCompleteListener(new OnCompleteListener<GetTokenResult>() {
public void onComplete(#NonNull Task<GetTokenResult> task) {
if (task.isSuccessful()) {
String idToken = task.getResult().getToken();
// Send token to your backend via HTTPS
// ...
} else {
// Handle error -> task.getException();
}
}
});
A little about OAuth 2.0
Whenever a user signs up to your app/website via Google or 3rd Party, an Authorization Code, this Authorization Code is exchanged for an AccessToken & RefreshToken.
The AccessToken sent via Google are valid generally for 60 minutes.
Offline Access (Server Side)
Let's break it down to two parts:
If your need to update within 60 minutes of user's last activity
You can use firebase along with gapi to achieve that. You'll be provided with the AccessToken that can be sent back to server to add to calendar.
More info on implementation
If you need to update after 60 minutes of user's last activity
Firebase & gapi's most method handle the AuthorizationCode flow internally. They even further refresh the AccessToken after 60 minutes. This is beneficial for most developers as they won't have a headache of managing all the tokens.
This method but, hides RefreshToken & AuthorizationCode from the developer. That is even if your server has the access token, it won't be able to refresh it and it would be deemed useless.
To achieve complete offline access, in the initial request to get AuthorizationCode you will need to send a HTTP GET parameter access_type to offline
GAPI provides you with grantOfflineAccess() method which returns the AuthorizationCode that can be later used on your server to fetch access token & refresh token.
Note: If you are storing AuthorizationCode in your database, make sure it is secure. The limitation in Firebase are set due to security reason. It is more secure to not talk with AuthorizationCode generally.
More links
https://developers.google.com/identity/protocols/oauth2/web-server
https://developers.google.com/identity/sign-in/web/reference
https://developers.google.com/identity/sign-in/web/server-side-flow
https://developers.google.com/identity/sign-in/web/backend-auth
Retrieve Google Access Token after authenticated using Firebase Authentication
I can sign in users to Firebase using this HTTP API:
How do I sign out users, so that the Firebase idToken and refreshToken can no longer be used?
Also, how long is the refreshToken valid for?
If my user does not use my app for weeks, can I still use the refreshToken or will I need to get a fresh Google Sign In idToken and exchange it for a Firebase (idToken, refreshToken) pair via the /identitytoolkit/v3/relyingparty/verifyAssertion API?
I don't believe there is a sign out endpoint. You could try doing a redirect to https://accounts.google.com/Logout but I suspect that is signing out from all Google services which might not be a great idea.
The whole point of Refresh Tokens is that they can be used to access resources whether or not the user is present and signed in, so your comment "How do I sign out users, so that the Firebase idToken and refreshToken can no longer be used" is an oxymoron.
A Refresh Token is theoretically valid until a user specifically revokes it, but your app should code for the possibility that Google has expired it.
The client cannot directly revoke the ID token via the REST API, but both the Firebase Auth client SDKs (ex: Android) and the Auth Admin SDK do support it. So if your client platform isn't supported, but you are able to create a small server implementation (maybe through Firebase/Cloud Functions), you can create an HTTP endpoint that triggers ID token revocation.
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.