awslabs / aws-jwt-verify

JS library for verifying JWTs signed by Amazon Cognito, and any OIDC-compatible IDP that signs JWTs with RS256, RS384, RS512, ES256, ES384, and ES512
Apache License 2.0
632 stars 45 forks source link

[BUG] Improve discoverability of the timeout parameter for fetch requests (in docs and/or code) #133

Open DannyBoris opened 1 year ago

DannyBoris commented 1 year ago

Describe the bug Please provide a clear and concise description of what the bug is. Trying to decode a token generated by Cognito results in Failed to fetch jwks. I've double checked all credentials (AWS_COGNITO_USER_POOL_ID, AWS_COGNITO_CLIENT_ID)

fetch the raw URL of the jwks from amazon works well - The json is retrieved.

Versions Which version of aws-jwt-verify are you using? 4.0.0 Are you using the library in Node.js or in the Web browser? Postman/Browser If Node.js, which version of Node.js are you using? (Should be at least 14) If Web browser, which web browser and which version of it are you using? 20.4.0 If using TypeScript, which version of TypeScript are you using? (Should be at least 4) 5.1.6

To Reproduce If you can, please provide a minimal code example that reproduces the bug. const decoded = await verifier.verify(token);

DannyBoris commented 1 year ago

Seems like the problem is a timeout after 1500 which is the default. When increasing the timeout to 5000, the request process successfully.

    async getJwks(jwksUri) {
        const existingFetch = this.fetchingJwks.get(jwksUri);
        if (existingFetch) {
            return existingFetch;
        }
        **const jwksPromise = this.fetcher.fetch(jwksUri, { responseTimeout: 5000 }).then((res) => {**
            assertIsJwks(res);
            return res;
        });
        this.fetchingJwks.set(jwksUri, jwksPromise);
        let jwks;
        try {
            jwks = await jwksPromise;
        }
        finally {
            this.fetchingJwks.delete(jwksUri);
        }
        this.jwksCache.set(jwksUri, jwks);
        return jwks;
    }
DannyBoris commented 1 year ago

Seems like the problem is a timeout after 1500 which is the default. When increasing the timeout to 5000, the request process successfully.

    async getJwks(jwksUri) {
        const existingFetch = this.fetchingJwks.get(jwksUri);
        if (existingFetch) {
            return existingFetch;
        }
        **const jwksPromise = this.fetcher.fetch(jwksUri, { responseTimeout: 5000 }).then((res) => {**
            assertIsJwks(res);
            return res;
        });
        this.fetchingJwks.set(jwksUri, jwksPromise);
        let jwks;
        try {
            jwks = await jwksPromise;
        }
        finally {
            this.fetchingJwks.delete(jwksUri);
        }
        this.jwksCache.set(jwksUri, jwks);
        return jwks;
    }

Is it possible to expose timeout setting to the user?

ottokruse commented 1 year ago

The timeout is user exposed: https://github.com/awslabs/aws-jwt-verify#configuring-the-jwks-response-timeout-and-other-http-options-with-jsonfetcher

See also this comment: https://github.com/awslabs/aws-jwt-verify/issues/72#issuecomment-1139609992

Let's leave this issue open because you have convinced me we need to do a better job of making this setting more obvious.