aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.4k stars 2.11k forks source link

getting `NoValidAuthTokens: No federated jwt` errors on devices whilst they should stay logged in #13541

Open mattiLeBlanc opened 1 week ago

mattiLeBlanc commented 1 week ago

Before opening, please confirm:

JavaScript Framework

Angular

Amplify APIs

Authentication

Amplify Version

v6

Amplify Categories

auth, api

Backend

None

Environment information

System: OS: macOS 14.4.1 CPU: (10) arm64 Apple M1 Max Memory: 25.34 GB / 64.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 20.14.0 - /usr/local/bin/node Yarn: 1.22.18 - ~/.npm-global/bin/yarn npm: 8.19.1 - ~/.npm-global/bin/npm pnpm: 9.0.0 - ~/.npm-global/bin/pnpm Browsers: Chrome: 126.0.6478.115 Safari: 17.4.1 npmPackages: @angular-devkit/build-angular: 18.0.1 => 18.0.1 @angular/animations: 18.0.0 => 18.0.0 @angular/cdk: 18.0.0 => 18.0.0 @angular/cli: 18.0.1 => 18.0.1 @angular/common: 18.0.0 => 18.0.0 @angular/compiler: 18.0.0 => 18.0.0 @angular/compiler-cli: 18.0.0 => 18.0.0 @angular/core: 18.0.0 => 18.0.0 @angular/forms: 18.0.0 => 18.0.0 @angular/material: 18.0.0 => 18.0.0 @angular/material-moment-adapter: 18.0.0 => 18.0.0 @angular/platform-browser: 18.0.0 => 18.0.0 @angular/platform-browser-dynamic: 18.0.0 => 18.0.0 @angular/router: 18.0.0 => 18.0.0 @angular/youtube-player: 18.0.0 => 18.0.0 @aws-amplify/core: ^6.3.1 => 6.3.1 @aws-sdk/client-acm: ^3.379.1 => 3.577.0 @aws-sdk/client-appsync: ^3.379.1 => 3.577.0 @aws-sdk/client-cognito-identity: ^3.379.1 => 3.577.0 @aws-sdk/client-cognito-identity-provider: ^3.379.1 => 3.577.0 @aws-sdk/credential-provider-ini: ^3.379.1 => 3.577.0 @iplab/ngx-file-upload: ^17.0.0 => 17.1.0 @types/jasmine: ~4.3.0 => 4.3.6 @types/node: 18.0.6 => 18.0.6 @types/prettier: 2.6.0 => 2.6.0 @types/uuid: ^10.0.0 => 10.0.0 @types/vimeo__player: ^2.16.3 => 2.18.3 @types/youtube: ^0.0.47 => 0.0.47 @vimeo/player: ^2.18.0 => 2.23.0 angular-google-tag-manager: ^1.9.0 => 1.9.0 aws-amplify: ^6.3.4 => 6.3.4 aws-cdk: ^2.118.0 => 2.133.0 aws-cdk-lib: ^2.118.0 => 2.133.0 aws-sdk: ^2.1531.0 => 2.1624.0 axios: ^1.3.4 => 1.7.1 constructs: ^10.3.0 => 10.3.0 dayjs: ^1.11.7 => 1.11.11 jasmine-core: ~4.5.0 => 4.5.0 karma: ~6.4.0 => 6.4.3 karma-chrome-launcher: ~3.1.0 => 3.1.1 karma-coverage: ~2.2.0 => 2.2.1 karma-jasmine: ~5.1.0 => 5.1.0 karma-jasmine-html-reporter: ~2.0.0 => 2.0.0 material-icons: ^1.13.12 => 1.13.12 nosleep.js: ^0.12.0 => 0.12.0 rxjs: ~7.8.0 => 7.8.1 source-map-support: ^0.5.21 => 0.5.21 tailwindcss: ^3.4.3 => 3.4.3 ts-node: ^10.9.1 => 10.9.2 tslib: ^2.3.0 => 2.6.2 typescript: ~5.4.5 => 5.4.5 uuid: ^10.0.0 => 10.0.0 web-animations-js: ^2.3.2 => 2.3.2 zone.js: ~0.14.2 => 0.14.6 zxcvbn: ^4.4.2 => 4.4.2 npmGlobalPackages: @angular/cli: 17.0.3 angular-http-server: 1.10.0 aws-cdk: 2.146.0 aws: 0.0.3-2 envinfo: 7.13.0 firebase-tools: 11.16.1 nativescript: 8.2.3 node-gyp: 8.4.1 npm: 8.19.1 pnpm: 9.0.0 yarn: 1.22.18

Describe the bug

My Angular error handler is reporting several Authentication related errors when doing Appsync calls:

No federated jwtNoValidAuthTokens: No federated jwt Runtime error running query getMediaPath. Authmode Cognito. Error: NoValidAuthTokens: No federated jwt Graphql Error running query getMediaPath. Authmode Cognito. Error: Unauthorized Error: Graphql Error running query getMediaPath. Authmode Cognito. Error: Unauthorized

These are all from different customers using our platform. I can't see in the stack trace what caused it because all the code is uglified and it happens in 3th party lib (amplify).

These users SHOULD be logged in, because our refresh token is set to multiple years expiry. What may happen, they are running on a tablet which goes to sleep,and next day they come back to the application and it tries to do a query, maybe before the refreshtoken fetched a new accesstoken?

I can't reproduce it on my macbook, ipad of lenove android tablet.

Am I looking at headers being filtered by corporate networks or is their something else I should do?

I configure my angular app by the books:

main.ts:

Amplify.configure(awsConfig.clientApp, {
  API: {
    GraphQL: {
      headers: async () => {
        try {
          // test if user still exists (could be removed via Admin Resident Unlock). It will then trigger an error and be caught in catch block
          // NOTE: This is doing a lot of unncessary calls to Cognito for ANY graphql request.
          // Better to use Grapql subscription to log a user out.
          await fetchUserAttributes();

          const currentSession = await fetchAuthSession();
          if (currentSession.tokens) {
            const idToken = currentSession.tokens.idToken?.toString();
            return { Authorization: idToken };
          } else {
            return undefined
          }
        } catch (error) {
          signOut()
          return undefined;
        }

      }
    }
  }
});

I am using the latest version of Amplify 6 and before I was using Amplify 5.4 I didnt not get these JWT errors. Maybe just authorisation errors.

Expected behavior

I expect no authorisation errors if refreshtoken is valid and app is activated

Reproduction steps

I don't even know how to reproduce it myself. It is happening on customers devices.

I realise this issue is vague, and it is for me too. I would have to get a hold of some of our users devices or talk their ID department to find out if has something to do with contentblockers or other security settings.

But I hope maybe these errors ring bells and you can give me a nudge in the right direction.

Code Snippet

// Put your code below this line.

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

israx commented 1 week ago

Hello @mattiLeBlanc. Sorry for any inconvenience using the library, and thank you for providing the code snippets.

Based on the code bellow, the fetchUserAttributes API will fail if there is not connectivity or if there is a network delay, hence hitting the catch block and logging the user out. So the absence of auth tokens would explain the No federated jwt error.

try {
          await fetchUserAttributes();
          const currentSession = await fetchAuthSession();
          if (currentSession.tokens) {
            const idToken = currentSession.tokens.idToken?.toString();
            return { Authorization: idToken };
          } else {
            return undefined
          }
        } catch (error) {
          signOut()
          return undefined;
        }

If you indeed are getting a NetworkError, a potential solution is to add a retry logic until the connection is back and then continue with the original flow.

ndaba1 commented 1 week ago

Hello, I can confirm that I am experiencing the same issue but on a Next.js v14 project. I'm using plain cognito (phone number + password) without any federated auth providers.

I don't have any logic to sign out the user as in the OP's issue. Here's a snippet of how I initialize my client

import amplifyConfig from "@repo/aws-exports";

Amplify.configure(amplifyConfig, { ssr: true });
ConsoleLogger.LOG_LEVEL = "DEBUG";

Then, I have the ssrClient utility initialized as follows:

import { createServerRunner } from "@aws-amplify/adapter-nextjs";
import { generateServerClientUsingCookies } from "@aws-amplify/adapter-nextjs/api";
import { cookies } from "next/headers";

import config from "@repo/aws-exports";

export const ssrClient = generateServerClientUsingCookies({
  cookies,
  config,
  authMode: "userPool",
});

export const { runWithAmplifyServerContext } = createServerRunner({
  config,
});

This issue occurs anytime I try to use the ssrClient to perform a query to appsync. Also, one weird thing I have noticed is that this seems to appear only on localhost. The production build seems to work okay (so far). This follows upgrading the latest versions of aws-amplify (6.3.7), @aws-amplify/adapter-nextjs (1.2.5) and next. (14.2.4)

Initially, I was getting a different No current user error (despite my tokens not being expired) as reported here. But after upgrading, this is the new error I am getting

cwomack commented 1 week ago

@ndaba1, thank you for the additional context here. We'll work on reproducing on our side and investigate this further.

ndaba1 commented 1 week ago

@cwomack any progress/updates on this ?