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

"No current user" error when calling graphql api endpoints in Next.js v14 project #12996

Closed
3 tasks done
ndaba1 opened this issue Feb 10, 2024 · 15 comments
Closed
3 tasks done
Assignees
Labels
Auth Related to Auth components/category question General question SSR Issues related to Server Side Rendering

Comments

@ndaba1
Copy link

ndaba1 commented Feb 10, 2024

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

Authentication, GraphQL API

Amplify Version

v6

Amplify Categories

auth, api

Backend

Amplify CLI

Environment information

  System:
    OS: Windows 11 10.0.22631
    CPU: (12) x64 12th Gen Intel(R) Core(TM) i5-12400F
    Memory: 9.12 GB / 31.84 GB
  Binaries:
    Node: 20.10.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.21 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 10.2.3 - C:\Program Files\nodejs\npm.CMD
    pnpm: 8.13.1 - ~\AppData\Roaming\npm\pnpm.CMD
  Browsers:
    Edge: Chromium (121.0.2277.112)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    @changesets/changelog-github: ^0.5.0 => 0.5.0 
    @changesets/cli: ^2.27.1 => 2.27.1 
    @commitlint/cli: ^18.4.3 => 18.4.3 
    @commitlint/config-conventional: ^18.4.3 => 18.4.3
    @knocklabs/node: ^0.5.0 => 0.5.0
    @repo/aws-types: workspace:^ => 0.1.0
    @repo/prettier-config: workspace:^0.1.0 => 0.1.0
    @repo/types: workspace:^ => 0.1.0
    @segment/analytics-next: ^1.62.0 => 1.62.0
    @segment/analytics-node: ^1.1.4 => 1.1.4
    @turbo/gen: ^1.11.2 => 1.11.2
    @types/node: ^20.10.5 => 20.10.5
    chalk: ^5.3.0 => 5.3.0
    husky: ^8.0.3 => 8.0.3
    lint-staged: ^15.2.0 => 15.2.0
    prettier: ^3.1.1 => 3.1.1
    prompts: ^2.4.2 => 2.4.2
    turbo: ^1.11.2 => 1.11.2
    typescript: ^5.3.3 => 5.3.3
  npmGlobalPackages:
    @aws-amplify/cli: 12.0.3
    @thejumba/auditable-transformer: 1.3.3
    eas-cli: 6.1.0
    pnpm: 8.13.1
    vercel: 33.0.2
    yarn: 1.22.21

Describe the bug

Recently, I've been getting this consistent error No current user on our Next.js v14 application. It appears ever so randomly and always when trying to invoke the amplify GraphQL API from a server component. I've tried multiple solutions such as checking that Amplify.configure or Auth.configure is only called in one place and also checking for duplicate amplify version as described here.

Since the app is running on Amplify v6, there's a utility constant ssrClient that is used to make all graphql api calls on server components as shown in the snippets below.

Expected behavior

The GraphQL API call should be made successfully without any errors being thrown

Reproduction steps

  1. Create a Next.js v14 application
  2. Setup amplify version 6
  3. Configure an amplify graphql api endpoint
  4. Setup SSR functionality for amplify
  5. Call said graphql api endpoint from a server component/server action using utilities provided from aws-amplify/adapter-nextjs package

Code Snippet

Amplify is configured in a file which exports a Providers component that wraps everything else in the app in the root layout.tsx

// app/providers.tsx
"use client"; 

import { Amplify } from "aws-amplify";
import { parseAmplifyConfig } from "aws-amplify/utils";
import amplifyConfig from "@repo/aws-exports";

Amplify.configure(parseAmplifyConfig(amplifyConfig), { ssr: true });

// ... rest of code

We then have some utilities exported for amplify ssr interactions:

// @/lib/amplify-ssr.tsx
import { cookies } from "next/headers";
import { createServerRunner } from "@aws-amplify/adapter-nextjs";
import { generateServerClientUsingCookies } from "@aws-amplify/adapter-nextjs/api";
import { parseAmplifyConfig } from "aws-amplify/utils";

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

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

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

And then we use the ssrClient

const res = await ssrClient.graphql({
    query: "someQuery",
    variables: {
       // query variables
    },
  })

Log output

// Put your logs below this line


aws-exports.js

const awsmobile = {
  "aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
  "aws_appsync_graphqlEndpoint": "https://XXXXXXXXXXXXXX.appsync-api.us-east-1.amazonaws.com/graphql",
  "aws_appsync_region": "us-east-1",
  "aws_cognito_identity_pool_id": "us-east-1:XXXXXXXXXXXXXX",
  "aws_cognito_mfa_configuration": "ON",
  "aws_cognito_mfa_types": [
    "SMS"
  ],
  "aws_cognito_password_protection_settings": {
    "passwordPolicyCharacters": [],
    "passwordPolicyMinLength": 8
  },
  "aws_cognito_region": "us-east-1",
  "aws_cognito_signup_attributes": [
    "EMAIL",
    "NAME",
    "PHONE_NUMBER"
  ],
  "aws_cognito_social_providers": [],
  "aws_cognito_username_attributes": [
    "PHONE_NUMBER"
  ],
  "aws_cognito_verification_mechanisms": [
    "PHONE_NUMBER"
  ],
  "aws_project_region": "us-east-1",
  "aws_user_files_s3_bucket": "XXXXXXXXXXXXXX",
  "aws_user_files_s3_bucket_region": "us-east-1",
  "aws_user_pools_id": "XXXXXXXXXXXXXX",
  "aws_user_pools_web_client_id": "XXXXXXXXXXXXXX",
  "oauth": {}
}

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

This is what keeps getting captured by sentry

Screenshot 2024-02-11 023709 Screenshot 2024-02-11 024458
@ndaba1 ndaba1 added the pending-triage Issue is pending triage label Feb 10, 2024
@cwomack cwomack added Auth Related to Auth components/category SSR Issues related to Server Side Rendering labels Feb 11, 2024
@nadetastic nadetastic added the GraphQL Related to GraphQL API issues label Feb 12, 2024
@nadetastic nadetastic self-assigned this Feb 12, 2024
@JackWSargent
Copy link

Have you tried doing Amplify.configure(awsConfig) on both the client components and server components or are you already doing that?

@ndaba1
Copy link
Author

ndaba1 commented Feb 15, 2024

According to the latest v6 docs,
Screenshot 2024-02-16 003112

@chrisbonifacio
Copy link
Member

chrisbonifacio commented Feb 16, 2024

Hi @ndaba1 👋 I was able to reproduce the "No current user" error when using the cookie based client on the server side. However, I realized that I had old credentials in Local Storage. I cleared them and then started getting Unauthorized errors.

Screenshot 2024-02-16 at 12 52 42 PM

I simply logged in again and was able to retrieve data with the userPool auth mode again.
Screenshot 2024-02-16 at 12 53 08 PM

So, it seems this is reproducible if you have expired tokens (including refresh), preventing Amplify from refreshing the cognito access token and resulting in the "No current user" error.

Can you confirm that your credentials are not expired and that you are able to reproduce this issue with a recently logged in user?

This is the schema I had while reproducing (using Amplify Gen 2 to build the backend)

const schema = a.schema({
  CommunityPost: a
    .model({
      title: a.string().required(),
      poll: a.hasOne("CommunityPoll"),
    })
    .authorization([a.allow.private()]),

  CommunityPoll: a
    .model({
      question: a.string().required(),
      answers: a.hasMany("CommunityPollAnswer").arrayRequired().valueRequired(),
    })
    .authorization([a.allow.private()]),

  CommunityPollAnswer: a
    .model({
      answer: a.string().required(),
      votes: a.hasMany("CommunityPollVote").arrayRequired().valueRequired(),
    })
    .authorization([a.allow.private()]),

  CommunityPollVote: a
    .model({ name: a.string() })
    .authorization([a.allow.private()]),
});

@ndaba1
Copy link
Author

ndaba1 commented Feb 16, 2024

@chrisbonifacio thank you for taking the time to look into this. Yes, the issue occurs even for recently logged in users. To your point, I do think its related to the tokens not being refreshed correctly for whatever reason. Some users actually get randomly redirected to the sign in page when trying to access an SSR page(with RSC) but upon inputting credentials, the error "There is already a signed in user" is returned. And if you refresh the page, then you seem to be logged in again.

@chrisbonifacio chrisbonifacio removed the GraphQL Related to GraphQL API issues label Feb 23, 2024
@chrisbonifacio chrisbonifacio removed their assignment Feb 23, 2024
@chrisbonifacio chrisbonifacio added bug Something isn't working and removed pending-triage Issue is pending triage labels Feb 23, 2024
@chrisbonifacio
Copy link
Member

Since I am able to reproduce the issue, I marked this as a bug for the team to investigate further. Seems more auth related than GraphQL related.

To be more confident that we can reproduce it under the same conditions as your application, can you share more details about your auth resource such as the expiration for your tokens?

If you are building a Gen 1 Amplify app, using the Amplify CLI, you can also run the following command and provide us the project identifier in the output. This will let us recreate your exact auth resource.

amplify diagnose --send-report

@ndaba1
Copy link
Author

ndaba1 commented Feb 28, 2024

Hey @chrisbonifacio
The project identifier is 1ce1eff4cf18e0517708247971fa723f

@ndaba1
Copy link
Author

ndaba1 commented Jun 6, 2024

Hello, is there any feedback ? The issue is still persistent

@HuiSF
Copy link
Member

HuiSF commented Jul 8, 2024

Hi @ndaba1 By reading "It appears ever so randomly and always when trying to invoke the amplify GraphQL API from a server component" I suspect that the issue was caused by a failure of fetchAuthSession() call internally triggered by .graphql(). This failure is specifically Cognito Rate Limit error. Every fetchAuthSession call in an isolated server context makes three different service calls. This is known and adjustable limitation from Cognito (See the callout in this section of documentation).

If you are using ssrClient to make multiple GraphQL API calls within one Server Component on one incoming request, there is a way to optimize it.

In the meantime, we are actively exploring a better solution to make fetchAuthSession more efficient. In addition, we have improved error throwing from the GraphQL APIs, the error object now contains a underlyingError property. You may log this property to record the underlying error that caused No current user or No federated jwt errors, so you can confirm and determine whether you need to adjust Cognito quotas accordingly.

@ndaba1
Copy link
Author

ndaba1 commented Jul 11, 2024

Hey @HuiSF ,
Thank you for your well detailed response. Let me try it then get back to you

@ndaba1
Copy link
Author

ndaba1 commented Jul 31, 2024

@HuiSF we tried your suggested solution and unfortunately, it doesn't seem to work

import type { GraphQLOptionsV6 } from "@aws-amplify/api-graphql";
import { cookies } from "next/headers";
import { createServerRunner } from "@aws-amplify/adapter-nextjs";
import { generateClient } from "aws-amplify/api/server";
import { parseAmplifyConfig } from "aws-amplify/utils";

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

const config = parseAmplifyConfig(awsExports);

const client = generateClient({ config });

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

export const ssrClient = {
  graphql: async <TQuery = unknown>(options: GraphQLOptionsV6<TQuery>) => {
    const res = await runWithAmplifyServerContext({
      nextServerContext: { cookies },
      operation: async (contextSpec) => {
        return client.graphql<TQuery>(contextSpec, {
          query: options.query,
          variables: options.variables,
          authMode: options.authMode,
        });
      },
    });

    return res;
  },
};

This is how we refactored the ssrClient. Are we missing anything here ?

@HuiSF
Copy link
Member

HuiSF commented Jul 31, 2024

Hi @ndaba1 thanks for following up.

Looking at your implementation, it's actually no difference from calling runWithAmplifyServerContext() multiple times in order to client.graphql() in a context.

The above linked comment, suggested that to make multiple client.graphql() within a single call of runWithAmplifyServerContext(). Where the calls of client.graphql() require creating the context only once.

@ndaba1
Copy link
Author

ndaba1 commented Jul 31, 2024

Hey @HuiSF, thank you for getting back to me so quickly.

I think I see what you mean:
The optimization can only be made for multiple GraphQL API calls made within the same incoming request for a server component but a new server context would still get created for any additional requests, right ? (Please correct me if I'm wrong)

And if that's the case, wouldn't still we risk running into the issue if there are a high number of concurrent requests for a server rendered page (from different users) ?

Also, would you kindly offer some more insights on which Cognito Service Quotas we'd try adjusting to help with this issue ? The callback in the docs doesn't specify which limits one would need to adjust. You mentioned

Every fetchAuthSession call in an isolated server context makes three different service calls.

but I'm not sure which service calls this would be

@HuiSF
Copy link
Member

HuiSF commented Jul 31, 2024

That's correct @ndaba1 the optimization was only for multiple GraphQL calls within one incoming request.

fetchAuthSession() on the server side now requires InitiateAuth (if client sent tokens are expired), GetId and GetCredentialsForIdentity these 3 service calls to assume a user session on the server side.

For your use case, I'd recommend first to monito the underlyingError of No current user or No federated jwt errors to ensure they are caused by the rate limit.

@HuiSF HuiSF added pending-response and removed bug Something isn't working labels Aug 13, 2024
@cwomack cwomack added the question General question label Aug 19, 2024
@cwomack cwomack self-assigned this Aug 27, 2024
@cwomack
Copy link
Member

cwomack commented Sep 3, 2024

@ndaba1, wanted to check in and see if you had further questions on this or are still blocked. Let us know!

@github-actions github-actions bot added the pending-maintainer-response Issue is pending a response from the Amplify team. label Sep 3, 2024
@cwomack cwomack removed the pending-maintainer-response Issue is pending a response from the Amplify team. label Sep 3, 2024
@cwomack
Copy link
Member

cwomack commented Sep 9, 2024

Closing this issue as we have not heard back from you. If you are still experiencing this, please feel free to reply back and provide any information previously requested and we'd be happy to re-open the issue.

Thank you!

@cwomack cwomack closed this as not planned Won't fix, can't repro, duplicate, stale Sep 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Auth Related to Auth components/category question General question SSR Issues related to Server Side Rendering
Projects
None yet
Development

No branches or pull requests

6 participants