firebase-js-sdk
firebase-js-sdk copied to clipboard
Auth User Token still works after logout
- Operating System version: OSX 10.12.6
- Firebase SDK version: firebase 4.3.0
- Firebase Product: auth
Describe the problem
When I reload my Angular-4-based webpage, I reacquire the Firebase user token, via:
firebase.auth().onIdTokenChanged( user => {
if (user) { user.getIdToken().then( (token:string) => {
...save token...
})
})
and I have access to my password-protected Firebase database. However, this still works after I have logged out, via:
firebase.auth().signOut();
How can this happen? How should I be logging out if that is not correct? How do I get a status back from signOut()?
signOut() returns a promise which you can monitor for completion.
What exactly is it that still works after signing out? Using the SDK normally surely would not. But without a minimal and complete repro here it's hard to say what you're getting at.
If you're manually managing the Firebase ID token and passing that to a server process or something similar, the token is good until it expires (standard JWT). Since you've gone into DIY territory, it's your job to dispose of it when you want it to stop working, or wait for the expiration.
Note that I'm fairly sure you can manually revoke access from the admin panel, but that's a bit of a different process and probably not what you're looking for here.
arrrg...i was doing a nice detailed reply, when I did a sanity check that it happens in safari too, and not just chrome...once I logged out in safari, I stopped getting the symptom on chrome. D'OH! (I was using the same login on both browsers). This smells really bad, but I'll leave this on the far back burner until I have the time to sort out the (now more arcane) steps to reproduce the actual problem.
That does seem bad. Looking forward to getting some more repro steps!
@katowulf This happens to me as well in an Emberfire App.
- I am logged in with more than one browser (Firefox & Chrome on Ubuntu)
- I logout in one browser
- The promise
firebase.auth().signOut();completes fine - I refresh the App it thinks I am logged in still.
If I logout in ALL browsers I stay logged out after refresh.
There was a small synchronization issue, which should be fixed in the upcoming 4.6.0 release. Though, I think your situation is different. The other issue happened only rarely.
@bojeil-google what happens to ME and to @polyglotinc is the same so are you saying that OUR issue is really a "Multiple Browser signin prevents signout" issue?
I meant, the issue that was solved by the bug I mentioned which was fixed in https://firebase.google.com/support/release-notes/js#4.6.0 Can you check after sign out that localStorage is cleared from the currentUser?
@bojeil-google cc: @polyglotinc
- I am logged in with more than one browser (Firefox & Chrome on Ubuntu)
- In Chrome I see it is IN Local Storage
- I logout in one browser (Chrome)
- The promise firebase.auth().signOut(); completes fine
- In Chrome I see it is NO LONGER IN Local Storage
- I refresh the App it thinks I am logged in still
- In Chrome I see it is AGAIN IN Local Storage
Hey @brendanoh, can you try testing with the latest version 4.6.0? I tested with Chrome and Firefox in a Linux environment and was not able to reproduce it with that version. I opened multiple windows, signed in in one and then signed out in the same one, refreshed and the user was still signed out.
@bojeil-google
I am on 3.9 now as installed via EmberFire. I will try 4.6. Also, I am having the issue on localhost but I havent tested on a production domain.
Wow, very broken api, im having the same issues.
Hey @AmitShah can you provide more context on your issue? Is this regarding the user not signing out properly? As I mentioned, there was an edge case issue which we recently fixed. This should no longer be an issue. I am just not sure what exactly you are encountering as I can't replicate the above scenario described by @brendanoh.
The topic title is confusing here. I want to clarify that a token will remain active until the end of its natural lifetime even after sign out. In fact, you can keep a reference to a user and then sign out. The user would still be functional but will stop being persisted as currentUser. This is the expected behavior. If you are having that user persist after sign out, please provide us with a way to replicate it so we can fix it.
Thanks @bojeil-google for a bit of clarification. I didn't realize that a token would still be active until its natural lifetime expiration. So I was seeing my Java verification of ID Token was still passing even after signing out. That works for me. I can simply handle it on the client side. Thank you.
Is there any progress on this issue?
Just to clarify is it expected for the user's auth credentials to persist in local storage after logout? and is it the client side job to removed credentials from local storage?
Thanks,
Should this issue be closed it looks like firebase has switched from local storage to IndexDb. This issue looks more current https://github.com/firebase/firebase-js-sdk/issues/449
For anyone looking for clean-ish workaround, you can append a query string param right before redirecting the user away using signInWithRedirect. Current page query params will be picked up by signInWithRedirect and will be carried back by the flow. Then, after user is redirected back, just check for presence of the parameter. If the query param is absent on page load, clearly the user did not come back from redirect flow and you can skip calling getRedirectResult entirely, thus avoiding the whole issue.
In addition however, I would expect sign out to be able to purge all user data from the browser, even if as optional API.
I was facing similar issue. Below is the link which provides workaround,
https://groups.google.com/forum/#!topic/firebase-talk/gxBm0WKCuIY
For internally tracking the clarification/update to the docs, b/156547460
For anyone looking for clean-ish workaround, you can append a query string param right before redirecting the user away using
signInWithRedirect. Current page query params will be picked up bysignInWithRedirectand will be carried back by the flow. Then, after user is redirected back, just check for presence of the parameter. If the query param is absent on page load, clearly the user did not come back from redirect flow and you can skip callinggetRedirectResultentirely, thus avoiding the whole issue.In addition however, I would expect sign out to be able to purge all user data from the browser, even if as optional API.
The firebase realize auto auth from back result with session data, how to prevent that auto auth and signInWithCredential? This error persiste here.
logout simply doesn't "revoke" the idToken.
this is very bad and insecure.
the expected behavior is that when the user clicks logout, it won't be able to use the token again.
logout simply doesn't "revoke" the idToken.
- I copied the request (curl) of a regular request that requires auth
- logout
- execute the request with the "old" token
- request returns 200.
I even have "checkRevoked" set to true on server side
const checkRevoked = true
const decodedToken = await firebaseService.admin
.auth()
.verifyIdToken(idToken, checkRevoked);
EDIT
I was able to MANUALLY revoke the token by using this method:
await firebaseService.admin.auth().revokeRefreshTokens(request.context.uid);
not great, as I need to do an extra call to the server. but it's actually working as expected (only if you check have checkRevoked flag on verifyIdToken )
Thanks for the update. You're right that logging out does not revoke the idToken automatically. we will document this in the reference docs.
I'm sorry but this seems a really lazy "solution" to not fix a security risk and merely put an obscure, sure to be missed, note someplace that the logout function doesn't really logout. WHY ISN'T THIS REALLY BEING FIXED? AND, after all these years?! I wrote this bug report so many years ago, that I've been retired for 4 years already! (no, not joking)
On Apr 26, 2023, at 5:18 AM, prameshj @.***> wrote:
Closed #158 https://github.com/firebase/firebase-js-sdk/issues/158 as completed via #7253 https://github.com/firebase/firebase-js-sdk/pull/7253.
— Reply to this email directly, view it on GitHub https://github.com/firebase/firebase-js-sdk/issues/158#event-9098546891, or unsubscribe https://github.com/notifications/unsubscribe-auth/AASDJ7PP52F6K56ABSJJTYTXDCHYFANCNFSM4D2SRDQQ. You are receiving this because you were mentioned.
Fair point. The documentation fix was needed at the minimum, but we can make it more easy to find. Revoking the idToken(including all id and refresh tokens for a given user) can be done using the admin SDK as called out above - https://github.com/firebase/firebase-admin-node/blob/294bffdd0b438ce9cd3a440fbadd40b52cfe0a6c/src/auth/auth-api-request.ts#L1514 does it.
Modifying signOut to revoke ALL idTokens and refresh tokens issued before that time is a breaking change and would not be the intended behavior. (user signed in on multiple devices, clicks signOut on device1, their login session on device2 is also lost). idTokens have a lifetime of 1 hour
I am reopening this, so we can document this behavior more clearly in the sign out sections of our documentation
cc @kevinthecheung @prameshj
Modifying
signOutto revoke ALL idTokens and refresh tokens issued before that time is a breaking change and would not be the intended behavior. (user signed in on multiple devices, clicks signOut on device1, their login session on device2 is also lost). idTokens have a lifetime of 1 hour
agree about the above, but you need to revoke that specific refresh token and id token, not the whole tokens. so other devices using different tokens won't get affected
agree about the above, but you need to revoke that specific refresh token and id token, not the whole tokens. so other devices using different tokens won't get affected
What's the most effective approach to accomplish this ^^ today?
This specific behavior appears to pose a security risk. After the signout() function is invoked, if the user retains the refreshToken, they are still able to generate a new access token using it.
What is the optimal method to revoke both the refreshToken and accessToken for that specific session without impacting the user's session on other devices?
From the documentation if we follow the approach mentioned here, we would just revoke all the refresh tokens for that user. https://github.com/firebase/firebase-js-sdk/issues/158#issuecomment-1510436547
Hi, I ran into this problem as well. Removing tokens across all devices is a very annoying experience. Firebase, can you please make the revoke function revoke only the token being used on the device?
Same issue I am facing even after 5 years. I am calling firebase function using client SDK where I am checking "request.auth.uid" to find user state (before login). Even after calling "auth.signOut" idToken is sent in the request.