auth0 / node-oauth2-jwt-bearer

Monorepo for libraries that protect Node APIs with OAuth2 Bearer JWTs
MIT License
95 stars 31 forks source link

500 Error thrown when deployed to GCP App Engine #114

Closed SpiegelSoft closed 1 year ago

SpiegelSoft commented 1 year ago

Checklist

Description

When an app is deployed to the App Engine in the Google Cloud Platform, and the middleware is defined as follows:

const jwtCheck = auth({
  audience: 'https://MY_AUDIENCE_URL/',
  issuerBaseURL: 'https://MY_ISSUER_URL/',
  tokenSigningAlg: 'RS256',
});

app.use(jwtCheck);

app.get('/', async (req, res) => {
  console.log('Auth: %s', JSON.stringify(req.auth));
  console.log('Headers: %s', JSON.stringify(req.headers));
  console.log('Body: %s', JSON.stringify(req.body));
  console.log('Query: %s', JSON.stringify(req.query));
  const TOKEN_RE = /^Bearer (.+)$/i;
  if (typeof req.headers.authorization === 'string') {
    const match = req.headers.authorization.match(TOKEN_RE);
    if (!!match) {
      res.send(`${match[1]}`);
    }
  }
});

and then a request is sent to the App Engine URL using the CURL protocol, i.e.

curl --verbose --request GET \
  --url https://MY_APP_ENGINE_URL/ \
  --header 'Accept: application/json'  --header 'authorization: Bearer 

the result of the CURL request is a 500 error. The App Engine shuts down because of this request.

However, if the auth check is changed to

const jwtCheck = auth({
  audience: 'https://MY_AUDIENCE_URL/',
  issuerBaseURL: 'https://MY_ISSUER_URL/',
  authRequired: false,
  tokenSigningAlg: 'RS256',
});

then the call to the endpoint succeeds, and the req.auth field is populated correctly.

I suspect that this is because the GCP App Engine generates some kind of preflight request that causes the middleware to throw an error.

Reproduction

  1. Create a GCP App Engine project using the code snippets shown above (without changing the authRequired field).
  2. Deploy the GCP App Engine project.
  3. Create a m2m token using the oauth/token endpoint.
  4. Send a GET request to the / endpoint using the CURL protocol.
  5. Note that the GET request fails with a 500 error.
  6. Go to the App Engine logs, and note that the App Engine server is shut down.
  7. Add authRequired: true to the jwtCheck middleware.
  8. Observe that the GET request succeeds, and the req.auth field is populated.

Additional context

No response

express-oauth2-jwt-bearer version

1.5.0

Node.js version

18.14.0

adamjmcgrath commented 1 year ago

Hi @SpiegelSoft - thanks for raising this

Could you share the details of any errors in your App Engine logs? Otherwise there's not much I can suggest - the code you've shared looks correct

SpiegelSoft commented 1 year ago

Hi Adam -- many apologies, but I have switched to Fastify (not because of this issue, which actually didn't matter to me, because I was happy to set authRequired to false, but because the integration with Websockets is smoother). I'll revert and try again when I can find a bit of spare time.

adamjmcgrath commented 1 year ago

np @SpiegelSoft - happy to reopen when you provide some more details