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.45k stars 2.13k forks source link

Server-Side Google Login Error: "Logins Don't Match" When Fetching User Information #13808

Closed nak1b closed 2 months ago

nak1b commented 2 months ago

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

Authentication

Amplify Version

v6

Amplify Categories

auth

Backend

None

Environment information

``` # Put output below this line System: OS: macOS 14.2.1 CPU: (12) arm64 Apple M3 Pro Memory: 300.05 MB / 18.00 GB Shell: 5.9 - /bin/zsh Binaries: Node: 20.9.0 - ~/.nvm/versions/node/v20.9.0/bin/node Yarn: 1.22.22 - ~/Desktop/ptc/alpha-post-test-coach/web/node_modules/.bin/yarn npm: 10.1.0 - ~/.nvm/versions/node/v20.9.0/bin/npm Watchman: 2024.07.01.00 - /opt/homebrew/bin/watchman Browsers: Chrome: 128.0.6613.121 Safari: 17.2.1 npmPackages: @ampproject/toolbox-optimizer: undefined () @aws-amplify/adapter-nextjs: ^1.2.16 => 1.2.17 @aws-amplify/adapter-nextjs/api: undefined () @aws-amplify/adapter-nextjs/data: undefined () @aws-amplify/ui-react: ^6.1.13 => 6.1.13 @aws-amplify/ui-react-internal: undefined () @babel/core: undefined () @babel/runtime: 7.22.5 @commitlint/cli: ^19.3.0 => 19.3.0 @commitlint/config-conventional: ^19.2.2 => 19.2.2 @edge-runtime/cookies: 4.0.2 @edge-runtime/ponyfill: 2.4.1 @edge-runtime/primitives: 4.0.2 @foobar404/wave: ^2.0.5 => 2.0.5 @google-cloud/text-to-speech: ^5.0.1 => 5.3.0 @hapi/accept: undefined () @hookform/resolvers: ^3.3.4 => 3.4.2 @hookform/resolvers/ajv: 1.0.0 @hookform/resolvers/arktype: 1.0.0 @hookform/resolvers/class-validator: 1.0.0 @hookform/resolvers/computed-types: 1.0.0 @hookform/resolvers/effect-ts: 1.0.0 @hookform/resolvers/io-ts: 1.0.0 @hookform/resolvers/joi: 1.0.0 @hookform/resolvers/nope: 1.0.0 @hookform/resolvers/superstruct: 1.0.0 @hookform/resolvers/typanion: 1.0.0 @hookform/resolvers/typebox: 1.0.0 @hookform/resolvers/valibot: 1.0.0 @hookform/resolvers/vest: 1.0.0 @hookform/resolvers/yup: 1.0.0 @hookform/resolvers/zod: 1.0.0 @mswjs/interceptors: undefined () @napi-rs/triples: undefined () @next/font: undefined () @next/react-dev-overlay: undefined () @opentelemetry/api: undefined () @radix-ui/react-accordion: ^1.1.2 => 1.1.2 @radix-ui/react-avatar: ^1.0.4 => 1.0.4 @radix-ui/react-dialog: ^1.0.5 => 1.0.5 @radix-ui/react-dropdown-menu: ^2.0.6 => 2.0.6 (1.0.0) @radix-ui/react-icons: ^1.3.0 => 1.3.0 @radix-ui/react-label: ^2.0.2 => 2.0.2 @radix-ui/react-radio-group: ^1.1.3 => 1.1.3 @radix-ui/react-scroll-area: ^1.0.5 => 1.0.5 @radix-ui/react-select: ^2.0.0 => 2.0.0 @radix-ui/react-slot: ^1.0.2 => 1.0.2 (1.0.0) @radix-ui/react-switch: ^1.0.3 => 1.0.3 @radix-ui/react-toast: ^1.1.5 => 1.1.5 @radix-ui/react-tooltip: ^1.0.7 => 1.0.7 @segment/ajv-human-errors: undefined () @sentry/nextjs: ^7.103.0 => 7.116.0 @tailwindcss/typography: ^0.5.10 => 0.5.13 @tanstack/query-codemods: 4.24.3 @tanstack/react-query: ^5.36.2 => 5.37.1 @types/amplify: ^1.1.28 => 1.1.28 @types/katex: ^0.16.7 => 0.16.7 @types/lodash.keyby: ^4.6.9 => 4.6.9 @types/node: ^20 => 20.12.12 @types/react: ^18 => 18.3.2 @types/react-dom: ^18 => 18.3.0 @types/react-html-parser: ^2.0.6 => 2.0.6 @types/react-lottie: ^1.2.10 => 1.2.10 @vercel/nft: undefined () @vercel/og: 0.5.15 acorn: undefined () add: ^2.0.6 => 2.0.6 amphtml-validator: undefined () anser: undefined () arg: undefined () assert: undefined () async-retry: undefined () async-sema: undefined () autoprefixer: ^10.0.1 => 10.4.19 aws-amplify: 6.5.3 => 6.5.3 aws-amplify/adapter-core: undefined () aws-amplify/analytics: undefined () aws-amplify/analytics/kinesis: undefined () aws-amplify/analytics/kinesis-firehose: undefined () aws-amplify/analytics/personalize: undefined () aws-amplify/analytics/pinpoint: undefined () aws-amplify/api: undefined () aws-amplify/api/server: undefined () aws-amplify/auth: undefined () aws-amplify/auth/cognito: undefined () aws-amplify/auth/cognito/server: undefined () aws-amplify/auth/enable-oauth-listener: undefined () aws-amplify/auth/server: undefined () aws-amplify/data: undefined () aws-amplify/data/server: undefined () aws-amplify/datastore: undefined () aws-amplify/in-app-messaging: undefined () aws-amplify/in-app-messaging/pinpoint: undefined () aws-amplify/push-notifications: undefined () aws-amplify/push-notifications/pinpoint: undefined () aws-amplify/storage: undefined () aws-amplify/storage/s3: undefined () aws-amplify/storage/s3/server: undefined () aws-amplify/storage/server: undefined () aws-amplify/utils: undefined () babel-packages: undefined () browserify-zlib: undefined () browserslist: undefined () buffer: undefined () bytes: undefined () ci-info: undefined () class-variance-authority: ^0.7.0 => 0.7.0 cli-select: undefined () client-only: 0.0.1 clsx: ^2.1.0 => 2.1.1 (2.0.0) comment-json: undefined () compression: undefined () conf: undefined () constants-browserify: undefined () content-disposition: undefined () content-type: undefined () cookie: undefined () cross-spawn: undefined () crypto-browserify: undefined () css.escape: undefined () data-uri-to-buffer: undefined () debug: undefined () devalue: undefined () domain-browser: undefined () edge-runtime: undefined () envsafe: ^2.0.3 => 2.0.3 eslint: ^8 => 8.57.0 eslint-config-next: 14.0.4 => 14.0.4 events: undefined () find-cache-dir: undefined () find-up: undefined () fresh: undefined () get-orientation: undefined () glob: undefined () gzip-size: undefined () http-proxy: undefined () http-proxy-agent: undefined () https-browserify: undefined () https-proxy-agent: undefined () husky: ^9.0.11 => 9.0.11 icss-utils: undefined () ignore-loader: undefined () image-size: undefined () is-animated: undefined () is-docker: undefined () is-wsl: undefined () jest-worker: undefined () json5: undefined () jsonwebtoken: undefined () katex: ^0.16.9 => 0.16.10 livekit-client: ^2.0.10 => 2.1.5 loader-runner: undefined () loader-utils: undefined () lodash.curry: undefined () lodash.keyby: ^4.6.0 => 4.6.0 lru-cache: undefined () lucide-react: ^0.316.0 => 0.316.0 micromatch: undefined () microsoft-cognitiveservices-speech-sdk: ^1.34.0 => 1.36.0 mini-css-extract-plugin: undefined () nanoid: ^5.0.4 => undefined (5.0.7, , 3.3.7) native-url: undefined () neo-async: undefined () next: 14.0.4 => 14.0.4 next-themes: ^0.2.1 => 0.2.1 node-fetch: ^3.3.2 => 3.3.2 (2.7.0, ) node-html-parser: undefined () ora: undefined () os-browserify: undefined () p-limit: undefined () p-map: ^7.0.2 => 7.0.2 path-browserify: undefined () pino: ^9.1.0 => 9.1.0 platform: undefined () postcss: ^8 => 8.4.38 (8.4.31) postcss-flexbugs-fixes: undefined () postcss-modules-extract-imports: undefined () postcss-modules-local-by-default: undefined () postcss-modules-scope: undefined () postcss-modules-values: undefined () postcss-preset-env: undefined () postcss-safe-parser: undefined () postcss-scss: undefined () postcss-value-parser: undefined () posthog-js: ^1.129.0 => 1.133.0 posthog-js-react: 1.0.0 prettier: ^3.2.5 => 3.2.5 process: undefined () punycode: undefined () querystring-es3: undefined () raw-body: undefined () react: ^18 => 18.3.1 react-builtin: undefined () react-dom: ^18 => 18.3.1 react-dom-builtin: undefined () react-dom-experimental-builtin: undefined () react-experimental-builtin: undefined () react-hook-form: ^7.49.3 => 7.51.5 (7.52.1) react-html-parser: ^2.0.2 => 2.0.2 react-html-parser-demo: 0.0.0 react-icons: ^5.2.1 => 5.2.1 react-is: 18.2.0 react-lottie: ^1.2.4 => 1.2.4 react-markdown: ^9.0.1 => 9.0.1 react-refresh: 0.12.0 react-server-dom-turbopack-builtin: undefined () react-server-dom-turbopack-experimental-builtin: undefined () react-server-dom-webpack-builtin: undefined () react-server-dom-webpack-experimental-builtin: undefined () regenerator-runtime: 0.13.4 remark-gfm: ^4.0.0 => 4.0.0 sass-loader: undefined () scheduler-builtin: undefined () scheduler-experimental-builtin: undefined () schema-utils: undefined () semver: undefined () send: undefined () server-only: 0.0.1 setimmediate: undefined () shell-quote: undefined () source-map: undefined () stacktrace-parser: undefined () stream-browserify: undefined () stream-http: undefined () string-hash: undefined () string_decoder: undefined () strip-ansi: undefined () superstruct: undefined () swr: ^2.2.4 => 2.2.5 tailwind-merge: ^2.2.1 => 2.3.0 tailwindcss: ^3.3.0 => 3.4.3 tailwindcss-animate: ^1.0.7 => 1.0.7 tar: undefined () terser: undefined () text-table: undefined () timers-browserify: undefined () transport: 0.0.1 tty-browserify: undefined () typescript: ^5 => 5.4.5 ua-parser-js: undefined () unistore: undefined () universal-cookie: ^4.0.4 => 4.0.4 util: undefined () uuid: ^9.0.1 => 9.0.1 vm-browserify: undefined () watchpack: undefined () web-vitals: undefined () webpack: undefined () webpack-sources: undefined () ws: undefined () yarn: ^1.22.22 => 1.22.22 zod: ^3.22.4 => 3.23.8 () zustand: ^4.5.2 => 4.5.2 npmGlobalPackages: @aws-amplify/cli: 12.12.4 @nestjs/cli: 10.3.0 corepack: 0.20.0 knex: 3.1.0 npm: 10.1.0 web: 0.1.0 yarn: 1.22.21 ```

Describe the bug

I have an application where users can log in through Google. However, I'm encountering an issue when attempting to retrieve user information on the server side. While the login works fine for one profile, it returns an error for another. This happens only when trying to access same application with different users on different google chrome profile.

Error:

Logins don't match. Please include at least one valid login for this identity or identity pool

Expected behavior

Profile 1: The server-side function should return the correct user information without any errors, similar to how it behaves on the client side.

Profile 2: The application should continue to work as expected, with the user information retrieved correctly on both the client and server sides.

Reproduction steps

Login with Profile 1

Use Google to log in with user1@gmail.com on Google Profile 1.

Login with Profile 2

Use Google to log in with user2@gmail.com on Google Profile 2. Retrieve User Info on Server Side

On Google Profile 1, attempting to fetch user data server-side results in the following error:

Logins don't match. Please include at least one valid login for this identity or identity pool

Fetching user info on client side for user on both Google Profile 1 and 2 works correctly.

Code Snippet

import {
  createKeyValueStorageFromCookieStorageAdapter,
  createUserPoolsTokenProvider,
  createAWSCredentialsAndIdentityIdProvider,
  runWithAmplifyServerContext
} from 'aws-amplify/adapter-core';
import { parseAmplifyConfig } from 'aws-amplify/utils';
import { fetchUserAttributes } from 'aws-amplify/auth/server';
import { cookies } from 'next/headers'

import config from '@/aws-exports';
import { ResourcesConfig } from 'aws-amplify';
import { FetchUserAttributesOutput } from 'aws-amplify/auth';

/**
 * Setup Instructions:
 * https://docs.amplify.aws/gen1/nextjs/build-a-backend/server-side-rendering/
 */

const amplifyConfig = parseAmplifyConfig(config);

const keyValueStorage = createKeyValueStorageFromCookieStorageAdapter({
  get(name: string) {
    const cookieStore = cookies()
    const cookie = cookieStore.get(name);
    return cookie;
  },
  getAll() {
    const cookieStore = cookies();
    return cookieStore.getAll();
  },
  set(name, value) {
    const cookieStore = cookies();
    cookieStore.set(name, value);
  },
  delete(name) {
    const cookieStore = cookies()
    cookieStore.delete(name);
  }
});

type AuthConfig = NonNullable<ResourcesConfig['Auth']>;

const tokenProvider = createUserPoolsTokenProvider(
  amplifyConfig.Auth as AuthConfig,
  keyValueStorage
);

const credentialsProvider = createAWSCredentialsAndIdentityIdProvider(
  amplifyConfig.Auth as AuthConfig,
  keyValueStorage
);

export const getAuthSessionServerSide = async (): Promise<FetchUserAttributesOutput | null> => {
  return runWithAmplifyServerContext(
    amplifyConfig,
    {
      Auth: { tokenProvider, credentialsProvider }
    },
    async (contextSpec) => {
      const user = await fetchUserAttributes(contextSpec);
      return user;
    }
  );
};

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

cwomack commented 2 months ago

Hello, @nak1b and thank you for opening this issue. After testing this locally on our side with 2 different Google profiles, we didn't experience this issue. A few suggestions to see if we can narrow down what is causing this:

  1. Verify that the lastAuthUser within each profile contains a different value (rather than the same across both sessions) to ensure that the ID tokens are not being shared between the two Chrome profiles. This can be done by logging the following key within the cookieStore: CognitoIdentityServiceProvider.<your_user_pool_client_id>.LastAuthUser

  2. Can you confirm if the request sent to the server from both profiles contains different username?

  3. If the above both show different results, can you then double check that the Identity Pool ID being used when configuring Amplify is the correct one you'd expected? Asking this because typically the error mentioned in this issue is thrown when the wrong Identity Pool ID is being used.

  4. Is there a specific reason that you're looking to use the generic adapter instead of the adapter-nextjs (see here)?

nak1b commented 2 months ago

@cwomack Thank you for taking the time to comment and test this issue. We recently created a new Amplify project on AWS, but our repository was still using the old configurations. Initially, we thought that simply updating the aws-exports file would suffice. However, we had to replace the entire Amplify folder with the new project using amplify pull to resolve the issue.

Regarding your question about using a generic adapter, I was following the guide linked here to set it up. I will also review the Next.js adapter to see if I can get it to work.

cwomack commented 2 months ago

@nak1b, did you get a chance to review the adapter and see if it resolves the issue? Just wanted to check in and see if there's anything still blocking you. Thanks!

nak1b commented 2 months ago

@cwomack we are still seeing incremental issue with "Logins Don't Match" I will work on replacing the adaptor and provide update on my findings. Thank You.

cwomack commented 2 months ago

@nak1b, just wanted to check in and see if you had a chance to test the adapter. And when you mention that you're experiencing this incrementally with your users, is this only happening with a certain subset/specific provider? Can you double check to ensure that anywhere you're importing your config, you've updated it to use the most recent changes to ensure the identity pool and backend resources are aligned.

Let us know if you're still experiencing this!

nak1b commented 2 months ago

@cwomack We updated the adaptor last week and were testing the new next adaptor and we are not seeing this issue anymore. Thanks for your help.