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

Using verifyIdToken()` with the second argument causes serverless function to timeout #929

Closed
chiubaca opened this issue Jul 6, 2020 · 9 comments
Assignees

Comments

@chiubaca
Copy link

chiubaca commented Jul 6, 2020

  • Operating System version: Ubuntu Xenial 16.04
  • Firebase SDK version: 8.13.0
  • Firebase Product: auth
  • Node.js version: v12.18.0
  • NPM version: 6.14.4

Steps to reproduce:

Using verifyIdToken(idToken, true) with the second argument to check if the token has been revoked causes Netlify serverless Function to timeout.

Relevant Code:

Publish the following code below to a Netlify function, then hit the endpoint which includes a valid JWT with an "Authorization" header and the lambda function will consistently timeout.

However if you remove the second argument from verifyIdToken() and republish the function again, there are no issue at all.

const admin = require("firebase-admin")

const SERVICE_ACCOUNT = JSON.parse(process.env.FIREBASE_CONFIG);

if (!admin.apps.length) {
  admin.initializeApp({
    credential: admin.credential.cert(SERVICE_ACCOUNT)
  });
}

exports.handler = async function (event, context, callback) {

  try {
    // Extract JWT from header
    const JWT = event.headers.authorization;

    // Verify JWT, if user deleted, or JWT is invalid, this will throw an error
    const user = await admin.auth().verifyIdToken(JWT, true);

    callback(null, {
      statusCode: 200,
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(user)
    });
  } catch (error) {
    console.error("There was an error", error);
    callback(null, {
      statusCode: 400,
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ error })
    });
  }
};
@hiranya911
Copy link
Contributor

hiranya911 commented Jul 6, 2020

Can you reproduce the issue locally or in any other environment? Without a repro (or at least some error logs and more context) I don't think we can do much about this issue, since it works normally in our test environments.

@chiubaca
Copy link
Author

chiubaca commented Jul 6, 2020

Weirdly, the issue cant be reproduced on a local machine. It only occurs when it's published on Netlify.
If it helps, I have published two endpoints which I used to verify this issue personally.

broken:
https://deploy-preview-7--jottivity.netlify.app/.netlify/functions/broken
logs : https://app.netlify.com/sites/jottivity/functions/broken?scope=deploypreview:7

working:
https://deploy-preview-7--jottivity.netlify.app/.netlify/functions/working
logs: https://app.netlify.com/sites/jottivity/functions/working?scope=deploypreview:7

I think those logs are accessible if you have a Netlify account

Here are some example headers which can be used against both endpoints;

Host: deploy-preview-7--jottivity.netlify.app
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://github.com/firebase/firebase-admin-node/issues/929
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0, no-cache
TE: Trailers
Authorization: eyJhbGciOiJSUzI1NiIsImtpZCI6Ijc2MjNlMTBhMDQ1MTQwZjFjZmQ0YmUwNDY2Y2Y4MDM1MmI1OWY4MWUiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiYWxleGNoaXUxMUBnbWFpbC5jb20iLCJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vam90dGl2aXR5LWxpdmUiLCJhdWQiOiJqb3R0aXZpdHktbGl2ZSIsImF1dGhfdGltZSI6MTU5NDA2OTYyNiwidXNlcl9pZCI6InRlOXJmcUQzeDhhV25OQ0JpU1dZcnkwNXJHWDIiLCJzdWIiOiJ0ZTlyZnFEM3g4YVduTkNCaVNXWXJ5MDVyR1gyIiwiaWF0IjoxNTk0MDY5NjI2LCJleHAiOjE1OTQwNzMyMjYsImVtYWlsIjoiYWxleGNoaXUxMUBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImZpcmViYXNlIjp7ImlkZW50aXRpZXMiOnsiZW1haWwiOlsiYWxleGNoaXUxMUBnbWFpbC5jb20iXX0sInNpZ25faW5fcHJvdmlkZXIiOiJwYXNzd29yZCJ9fQ.A17KQaay0gbxjRVYJ0Zh5oAXu0E0vZ8CE4IlkiXf0fIFZn0rWbFqs2gxHxD_OTGvx5pqNVo5BTJOaCyEk8C5I9hNiyh8Mprd94pucJCT15TeG6O6-AXCNrxkfAs-E0K-RCrp6bXNZULXFTQTjIryGvBi-9c4yQF-m6d8yxFreIYJ_z2RJ6iYEr11qx8acnpcwHI3sg9VeBmkiguxWCAPYS4C7dVh2slWLsc8Hu2E65WMnPGR89wKwxEfWzQ180pUDvJFR3JdZ0IcZbAwxX9hPuxtb_6uzZhdUV9p1AksSkrZFuPW6BJQNAmBioxuwEutq9xZYP_WC9t_Zf45g9ZAPw
Pragma: no-cache

Cant guarantee that test JWT will be usable for long term though.

@hiranya911
Copy link
Contributor

Can't really speculate as to why something wouldn't work in a specific environment. Have you tried reaching out to the Netlify Support or developer community?

@chiubaca
Copy link
Author

chiubaca commented Jul 6, 2020

I have indeed, I've posted the same issue on the Netlify community forums - https://community.netlify.com/t/netlify-function-timeout-after-10-seconds-when-published/18220

And I've spent a few hours troubleshooting this issue on the Firebase slack where we were able to pinpoint the issue to that verifyIdToken() method which was causing the problem.

@hiranya911
Copy link
Contributor

Ok, that forum post actually helped.

This is often resolved by changing the function code to include calls to close “the connection”. As far as what “the connection” actually is, it is typically a connection to an API or database.

You need to clean up the App instance (app.delete()) to ensure proper clean up of the Admin SDK: https://firebase.google.com/docs/reference/admin/node/admin.app.App#delete

This is not required in most environments. But it appears it's required in Netlify.

@chiubaca
Copy link
Author

chiubaca commented Jul 7, 2020

nice, that worked! I included await admin.app().delete() just before returning the http response. now it works locally and also when published to Netlify without any timeouts 👍 .

It does seem like quite a daunting method to call though, just my own personal thoughts. However, thank you helping me finally get to bottom of this issue.

@hiranya911
Copy link
Contributor

It does seem like quite a daunting method to call though, just my own personal thoughts.

Yeah, it's not the best name, but we are stuck with it for historical reasons. Most applications don't need to call it explicitly (notably none of the Google Cloud Functions code require it). But some environments can be more picky about calling it.

@zaarheed
Copy link

I’m having a similar timeout issue on Netlify, but when using the JavaScript Web SDK. Is there an equivalent .delete() method to close the Firestore connection on the Web SDK too?

netlify/next-on-netlify#66 (comment)

@alexanvl
Copy link

alexanvl commented Sep 23, 2022

We started to see this error at 2022-09-23 09:49:08.055 PDT in the firebase-admin@11.0.1 package, running in a node:16 container within GKE. Setting the checkedRevoked parameter to false seems to resolve the issue and we're try to determine what caused it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants