Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

auth_time doesn't match user's lastSignInTime (always matches iat instead) #3608

Closed
lovelle-cardoso opened this issue Jul 22, 2021 · 8 comments · Fixed by #3611
Closed

auth_time doesn't match user's lastSignInTime (always matches iat instead) #3608

lovelle-cardoso opened this issue Jul 22, 2021 · 8 comments · Fixed by #3611

Comments

@lovelle-cardoso
Copy link
Contributor

[REQUIRED] Describe your environment

  • Operating System version: Windows 10 Home Version 20H2, Build 19042.1052
  • Browser version: Chrome Version 91.0.4472.164 (64-bit)
  • Firebase SDK version: firebase 9.0.0-beta.6
  • Firebase Product: Firestore Emulator, Database Emulator, Storage Emulator

[REQUIRED] Describe the problem

According to the documentation, auth_time should match the user's last sign in time, and iat should match the time this token was issued. This means auth_time should only be updated once, when the user signed in, and iat should change every hour when a new token is issued. This is not the case however. Despite what the documentation says, auth_time changes every hour at the same time as iat. This means auth_time always matches iat, and can't be used in security rules to check the time the user last signed in

https://firebase.google.com/docs/reference/admin/node/admin.auth.DecodedIdToken#auth_time

Steps to reproduce:

  1. Create the following firestore.rules file
rules_version = '2';
service cloud.firestore {
   match /databases/{database}/documents {
    allow read, write: if request.auth != null && request.auth.token.auth_time < request.auth.token.iat;
  }
}
  1. Use npm run serve to run the new rules in your local emulators
  2. Sign in as a user on your client app.

Expected Result:

All reads and writes should fail for about the first hour. But after an hour has passed (and firebase has automatically issued the user a new token) the reads and writes should start succeeding

Actual Result:

All reads and writes fail forever. This is because auth_time always changes in lock-step with iat, despite the documentation saying that auth_time should remain stable after login and only iat should change every hour.

@looptheloop88
Copy link

Hi @lovelle-cardoso, thanks for the report. To isolate the issue, are you only experiencing this issue using an emulator? I tried connecting or using the production (not emulator) instance and I was able to write Firestore data successfully after an hour.

@lovelle-cardoso
Copy link
Contributor Author

@looptheloop88 It's an emulator only issue I believe.

@looptheloop88
Copy link

Hi @lovelle-cardoso, thanks for the confirmation. Let me check this out with our engineers here and update this thread if I have any information to share. Thanks.

@looptheloop88
Copy link

Thanks for patiently waiting. I have filed an internal bug (b/194700929) for this issue. I will keep this thread posted for any updates or if I have any other information to share.

@yuchenshi yuchenshi transferred this issue from firebase/firebase-js-sdk Jul 26, 2021
@yuchenshi yuchenshi self-assigned this Jul 26, 2021
@yuchenshi
Copy link
Member

The Auth Emulator doesn't accurately emulate auth_time behavior right now -- we just picked something that works for most use cases. Thanks for bring this up to our attention.

As @looptheloop88 noted, we now track this internally for a fix. We are unable to promise any timeline for this, but if others also have this issue, adding a +1 on this issue can help us prioritize adding this to the roadmap.

@yuchenshi
Copy link
Member

Looks like the problematic line is

auth_time: toUnixTimestamp(new Date()),
-- we're also happy to review a PR with the fix and tests.

@lovelle-cardoso
Copy link
Contributor Author

lovelle-cardoso commented Jul 27, 2021

@looptheloop88 @yuchenshi All right I've submitted a PR with a fix and added a unit test for it: #3610

^ Actually, had to delete that PR and make a new one here since my commit author wasn't correct: #3611

lovelle-cardoso added a commit to lovelle-cardoso/firebase-tools that referenced this issue Jul 27, 2021
Made emulator auth_time match how auth_time is populated in production. (auth_time should match user's lastLoginAt in seconds)
@lovelle-cardoso
Copy link
Contributor Author

lovelle-cardoso commented Jul 27, 2021

@looptheloop88 @yuchenshi PR with fix and unit test is here: #3611

yuchenshi added a commit that referenced this issue Jul 28, 2021
* fix: emulator auth_time (#3608)

Made emulator auth_time match how auth_time is populated in production. (auth_time should match user's lastLoginAt in seconds)

* Check not null just in case lastLoginAt is 0 because of unit test clock mocking

* Advance clock to verify auth_time is not refresh time

* assert user.lastLoginAt is not undefined

* Apply suggestions from code review

* Format code.

Co-authored-by: Yuchen Shi <yuchenshi@google.com>
devpeerapong pushed a commit to devpeerapong/firebase-tools that referenced this issue Dec 14, 2021
* fix: emulator auth_time (firebase#3608)

Made emulator auth_time match how auth_time is populated in production. (auth_time should match user's lastLoginAt in seconds)

* Check not null just in case lastLoginAt is 0 because of unit test clock mocking

* Advance clock to verify auth_time is not refresh time

* assert user.lastLoginAt is not undefined

* Apply suggestions from code review

* Format code.

Co-authored-by: Yuchen Shi <yuchenshi@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment