Closed FabianRueckert closed 1 year ago
Hey @FabianRueckert,
Thanks for reporting the issue. INVALID_CUSTOM_TOKEN is returned from Firebase for malformed or expired tokens during token refresh. I will try to reproduce the issue with versions you have provided and get back to you
I am using cloud firebase.
@FabianRueckert what method are you using to login before calling const tokenResult = await firebaseUser.getIdTokenResult();
?
I am using StyledFirebaseAuth from firebaseui-web-react
Hey @FabianRueckert!
I created firebaseui
example with all the dependencies and versions you mentioned above: https://github.com/awinogrodzki/next-firebase-auth-edge/commit/7d325701a51124e89a9fc1379c3819411354188c
Unfortunately, I wasn't able to reproduce INVALID_CUSTOM_TOKEN
error.
Could you verify if the example works for you locally or it fails with the same error? If so, probably the issue is connected with configuration.
By the way, could you post me the configuration you are passing to authentication
middleware?
@FabianRueckert I will close the issue. Please let me know if the provided example works when you have a chance to test it. If the problem continues we will reopen the issue 👍
I'm experiencing the same issue, suddenly with no code changes I started receiving
node_modules/next-firebase-auth-edge/lib/auth/index.js (56:0) @ customTokenToIdAndRefreshTokens
⨯ Problem getting a refresh token: {"error":{"code":400,"message":"INVALID_CUSTOM_TOKEN","errors":[{"message":"INVALID_CUSTOM_TOKEN","domain":"global","reason":"invalid"}]}}
null
I'm not using firebaseui, and this is the IdTokenChangedHandler:
async (firebaseUser: FirebaseUser | null) => {
if (firebaseUser !== null) {
const idTokenResult = await firebaseUser.getIdTokenResult();
await fetch("/api/login", {
headers: {
Authorization: `Bearer ${idTokenResult.token}`,
},
});
setCurrentUser(fromClient(firebaseUser, idTokenResult));
if (redirect) {
router.push(redirect, { scroll: true });
} else {
router.refresh();
}
return;
} else if (currentUser !== undefined) {
await fetch("/api/logout");
setCurrentUser(undefined);
router.refresh();
}
}
Hey @bruno-de-queiroz!
Could you run npx next info
in project root and paste the result here?
What version of next-firebase-auth-edge
are you using?
Could you reproduce the issue with debug mode enabled and share some logs?
Sure, here we go:
$ npx next info
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP Tue Dec 19 21:36:30 -03 2023
Binaries:
Node: 20.3.1
npm: 9.6.7
Yarn: N/A
pnpm: N/A
Relevant Packages:
next: 14.1.4
eslint-config-next: 14.1.4
react: 18.2.0
react-dom: 18.2.0
typescript: 5.4.3
Next.js Config:
output: N/A
And the debug logs:
ⓘ next-firebase-auth-edge: Handle request
path: /api/login
ⓘ next-firebase-auth-edge: Handle authentication API route
ⓘ next-firebase-auth-edge: Handle request
path: /en/sign-in
ⓘ next-firebase-auth-edge: Missing authentication cookies
ⓘ next-firebase-auth-edge: Token is missing or has incorrect formatting. This is expected and usually means that user has not yet logged in
reason: MISSING_CREDENTIALS
ⓘ next-firebase-auth-edge: Get public keys from cache
expiresAt: 1711997683685
now: 1711975626219
digest: ev22VX2HDM4NRfoHlylb6lofBhpLXvQiHzCrCpGWf7M
cryptoRuntime: WebCryptoAPI
ⓘ next-firebase-auth-edge: Generated custom token based on provided idToken
customToken: <redacted>
ⓘ next-firebase-auth-edge: Missing authentication cookies
ⓘ next-firebase-auth-edge: Missing authentication cookies
ⓘ next-firebase-auth-edge: Token is missing or has incorrect formatting. This is expected and usually means that user has not yet logged in
reason: MISSING_CREDENTIALS
ⓘ next-firebase-auth-edge: Token is missing or has incorrect formatting. This is expected and usually means that user has not yet logged in
reason: MISSING_CREDENTIALS
⨯ node_modules/next-firebase-auth-edge/lib/auth/index.js (56:0) @ customTokenToIdAndRefreshTokens
⨯ Problem getting a refresh token: {"error":{"code":400,"message":"INVALID_CUSTOM_TOKEN","errors":[{"message":"INVALID_CUSTOM_TOKEN","domain":"global","reason":"invalid"}]}}
null
and version:
"next-firebase-auth-edge": "^1.4.2",```
Thanks!
As official docs suggest: INVALID_CUSTOM_TOKEN
: The custom token format is incorrect or the token is invalid for some reason (e.g. expired, invalid signature etc.)
I would need to examine your generated custom token:
ⓘ next-firebase-auth-edge: Generated custom token based on provided idToken
customToken: <redacted>
Could you share the value behind <redacted>
?
If there's some data in the token you wish not to share, you can use https://jwt.io/ to decode the token and obfuscate some fields. I am most interested in JWT header
, kid
and expiry dates
Maybe that helps, let me know :)
Funny not seeing a kid in the header
Apparently, the token has expired already, although I cleared the storages, cookies, etc and started the sign-in with firebase/auth
Not really, I'm using firebase/auth for the client-side signIn, with a real firebase account pointing to a live project
export const signIn = async (params: SignInParams) => {
switch (params.provider) {
case "google":
await signInWithPopup(
getAuth(),
getGoogleProvider(params.locale),
browserPopupRedirectResolver,
);
break;
case "email":
await signInWithEmailAndPassword(
getAuth(),
params.email,
params.password,
);
break;
}
};
Just for the sake: here is the full log line with the token:
ⓘ next-firebase-auth-edge: Generated custom token based on provided idToken
customToken: eyJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJodHRwczovL2lkZW50aXR5dG9vbGtpdC5nb29nbGVhcGlzLmNvbS9nb29nbGUuaWRlbnRpdHkuaWRlbnRpdHl0b29sa2l0LnYxLklkZW50aXR5VG9vbGtpdCIsImlhdCI6MTcxMjAwOTcxMiwiZXhwIjoxNzEyMDEzMzEyLCJpc3MiOiJ
maXJlYmFzZS1hZG1pbnNkay03NTQyYkBuZWVkbGVzLWM3OTM5LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic3ViIjoiZmlyZWJhc2UtYWRtaW5zZGstNzU0MmJAbmVlZGxlcy1jNzkzOS5pYW0uZ3NlcnZpY2VhY2NvdW50LmNvbSIsInVpZCI6IjV4QVRkQ1daa3ZXRFVXU3Yxa0VDVFJFellTRzIiLCJjb
GFpbXMiOnsiZW1haWxfdmVyaWZpZWQiOnRydWUsInNvdXJjZV9zaWduX2luX3Byb3ZpZGVyIjoiZ29vZ2xlLmNvbSJ9fQ.piA5cFl0D82zZlEB4g4XGokJPCHztFsrMir-TlJZh5qpbEYL2JqLlK2kTDnxOUkUvG7yRQh-ldB0ZV3o5vg7xMNjS5KZcppN_SN_DKfagXIHqcH7GSzx9ObYdHIHUnR-Wzf7aNBOdn3NkeJKqYhgI-WndIzTwbjWwALPvJylVCyb2Y_cqBS2qCrJ_X1fpcuoFPhxChLdmIsFck5jtOpBBknWgmKmZ_db5IfGrlOmfNfUwyRvmzNFu2rXMesgVbBJ-958V2HizNukrTJt7x1yD4A1McfoxKkrLZQuldORWeCFs8lHWHzIN1E5zpcWvIHzpRZTIWkRbPXJAxJwMw0o4Q
⨯ node_modules/next-firebase-auth-edge/lib/auth/index.js (56:0) @ customTokenToIdAndRefreshTokens
⨯ Problem getting a refresh token: {"error":{"code":400,"message":"INVALID_CUSTOM_TOKEN","errors":[{"message":"INVALID_CUSTOM_TOKEN","domain":"global","reason":"invalid"}]}}
null
Thanks!
Sorry, I confirmed that the customToken
has in fact the correct structure. It might be the expiry dates.
Are these logs from today? I've noticed that iat
and now
is about 1-2 days in the past.
Are you running the project locally? Is your system time up to date?
I've added a console.log to print the credentials after the signIn, and the token in the user.accessToken
decoded has the same format as the example you posted. So that customToken does not follow the original format.
Hmm I'm running local with WSL2, so I just ran wsl --shutdown
to restart the service and voilá, it is working again 🤦
Thanks @awinogrodzki for the debug session, but this is very interesting indeed.
No worries, glad we've worked it out!
It's worth to note here that remote authentication is usually time-sensitive process. If iat
(issued at) is suspiciously old, we can get rejected by Google.
Yup, I noticed that when I converted the exp and was pointing to 2 days ago that this was probably the problem, didn't expect WSL2 playing tricks on the system time
As soon as I call
This console error message shows up:
And no cookie is set.
tokenResult
contains a valid token however. Any idea what causes this? I am onfirebase 9.18.0
,firebase-admin 11.5.0
,next 13.2.4
,"next-firebase-auth-edge": "0.5.1"
with authentification middleware.