JWT's generated are invalid
Closed this issue · 5 comments
Hi, thanks for this library! It's helped a lot :)
I noticed however, the JWT's generated by the init
function are invalid, notably that they have an iat
of 0
and exp
of 3600
.
Notably,
const db = await Firestore.init({
uid: 'anything',
project_id: authConfig.projectId,
client_email: serviceUser.client_email,
private_key: serviceUser.private_key,
private_key_id: serviceUser.private_key_id
})
const a = await Firestore.get(db, 'users')
Would return the following error:
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
I don't know enough about JOSE to help debug or fix the actual issue, but I was able to get the library working with a JWT I generate myself using @tsndr/cloudflare-worker-jwt
(https://github.com/tsndr/cloudflare-worker-jwt):
const now = new Date().getTime() / 1000
const JWT = await jwt.sign({
iss: serviceUser.client_email,
sub: serviceUser.client_email,
aud: "https://firestore.googleapis.com/",
iat: now,
exp: now + 3600,
}, serviceUser.private_key, {algorithm: "RS256"})
Passing this into my own DB
object with the public key gives me better responses. Putting the two key's into jwt.io side by side reveals:
Firestore.init |
jwt.sign |
---|---|
I'm happy to open a PR that replaces jose
with @tsndr/cloudflare-worker-jwt
if you're okay with the library change.
I also received the "Request had invalid authentication credentials" error (it worked properly with native libraries).
I also received the "Request had invalid authentication credentials" error (it worked properly with native libraries).
@mjaskolski Can you toss your JWT generated with Fireworkers into https://jwt.io/'s Decoder and share the body? Use my screenshots as a guidance of what is and isn't safe to share publicly. If it's related to this issue you'll have an iat
of 0.
Soooo... Outside of fetch handlers, new Date()
will return a 0-date...
If you are, like me, tempted to created the JWT on the top level, it will have this odd iat: 0
and exp: 3600
.
Instead you'll have to create the JWT inside the fetch handler.
Personally I have my database abstraction make the JWT on-demand, and cache it.
(Also, check if before every request - I don't know how long cloudflare worker environment can persist, but I wouldn't be surprised if suddenly it lasts longer than an hour)
Hi,
I've recently come to learn that within a fetch handler, new Date()
returns the time of the last IO, to prevent timing attacks. Outside a fetch handler, it (the current time) is zero.
So @dralletje's solution of moving the JWT creation into fetch is the correct solution. I'm not sure why my solution worked at all actually!
Closing this because Cloudflare is silly.