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

SignInWithRedirect a custom provider returns authorization_code and state but doesn't login the user - v6 #13332

Closed jojimcNova closed 6 months ago

jojimcNova commented 6 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: Windows 10 10.0.19045 CPU: (16) x64 13th Gen Intel(R) Core(TM) i5-1350P Memory: 13.32 GB / 31.69 GB Binaries: Node: 20.11.0 - C:\Program Files\nodejs\node.EXE npm: 10.2.4 - C:\Program Files\nodejs\npm.CMD Browsers: Edge: Chromium (123.0.2420.97) Internet Explorer: 11.0.19041.3636 npmPackages: @ampproject/toolbox-optimizer: undefined () @aws-amplify/adapter-nextjs: ^1.1.5 => 1.1.5 @aws-amplify/adapter-nextjs/api: undefined () @aws-amplify/adapter-nextjs/data: undefined () @aws-amplify/ui-react: ^6.1.8 => 6.1.8 @aws-amplify/ui-react-internal: undefined () @babel/core: undefined () @babel/runtime: 7.22.5 @edge-runtime/cookies: 4.1.1 @edge-runtime/ponyfill: 2.4.2 @edge-runtime/primitives: 4.1.0 @emotion/cache: ^11.11.0 => 11.11.0 @emotion/react: ^11.11.4 => 11.11.4 @emotion/styled: ^11.11.5 => 11.11.5 @hapi/accept: undefined () @mswjs/interceptors: undefined () @mui/material: ^5.15.15 => 5.15.15 @mui/material-nextjs: ^5.15.11 => 5.15.11 @napi-rs/triples: undefined () @next/font: undefined () @opentelemetry/api: undefined () @types/node: ^20 => 20.12.7 @types/react: ^18 => 18.2.79 @types/react-dom: ^18 => 18.2.25 @vercel/nft: undefined () @vercel/og: 0.6.2 acorn: undefined () amazon-cognito-identity-js: ^6.3.12 => 6.3.12 amazon-cognito-identity-js/internals: undefined () amphtml-validator: undefined () anser: undefined () arg: undefined () assert: undefined () async-retry: undefined () async-sema: undefined () aws-amplify: ^6.2.0 => 6.2.0 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 () aws-sdk: ^2.1610.0 => 2.1610.0 babel-packages: undefined () browserify-zlib: undefined () browserslist: undefined () buffer: undefined () bytes: undefined () ci-info: undefined () cli-select: undefined () client-only: 0.0.1 commander: undefined () 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 () eslint: ^8 => 8.57.0 eslint-config-next: 14.2.2 => 14.2.2 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 () 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 () loader-runner: undefined () loader-utils: undefined () lodash.curry: undefined () lru-cache: undefined () mini-css-extract-plugin: undefined () nanoid: undefined () native-url: undefined () neo-async: undefined () next: 14.2.2 => 14.2.2 node-fetch: undefined () node-html-parser: undefined () ora: undefined () os-browserify: undefined () p-limit: undefined () path-browserify: undefined () picomatch: undefined () 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 () process: undefined () punycode: undefined () querystring-es3: undefined () raw-body: undefined () react: ^18 => 18.2.0 react-builtin: undefined () react-dom: ^18 => 18.2.0 react-dom-builtin: undefined () react-dom-experimental-builtin: undefined () react-experimental-builtin: undefined () react-is: 18.2.0 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 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 () source-map08: undefined () stacktrace-parser: undefined () stream-browserify: undefined () stream-http: undefined () string-hash: undefined () string_decoder: undefined () strip-ansi: undefined () superstruct: undefined () tailwindcss: ^3.4.1 => 3.4.3 tar: undefined () terser: undefined () text-table: undefined () timers-browserify: undefined () tty-browserify: undefined () typescript: ^5 => 5.4.5 ua-parser-js: undefined () unistore: undefined () util: undefined () vm-browserify: undefined () watchpack: undefined () web-vitals: undefined () webpack: undefined () webpack-sources: undefined () ws: undefined () zod: undefined () npmGlobalPackages: @aws-amplify/cli: 12.10.3 aws-cdk: 2.111.0 ```

Describe the bug

I'm trying to provide 2 ways to my user to login : 1 - Credentials 2 - Using SAML identity providers with a user pool

When trying to login with the second option using signInWithRedirect({ custom: custom-provider }), I can see that the oauth2/authorize call is done in the network, and I also see the following call which is http://localhost:3000/?code=[Authorization_Code]&state=[State_Code]

Afterword, there is no connection done, not even cookies saved.

Expected behavior

The user to be authentified, so I can retrieve the user informations for my application.

Reproduction steps

  1. Create new NextJS project
  2. Configure SAML identity provider with Cognito
  3. Create custom login page, and add following code as the button for sso connection (which is signInWithRedirect)

Code Snippet

// Put your code below this line.
'use client'

import Box from '@mui/material/Box/Box'
import Button from '@mui/material/Button/Button'
import { AuthUser, getCurrentUser, signInWithRedirect } from 'aws-amplify/auth';
import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { Hub } from 'aws-amplify/utils';
import 'aws-amplify/auth/enable-oauth-listener';

function SSOButton() {
  const router = useRouter();
  const provider = {
    custom: 'custom-provider'
  }

  const [user, setUser] = useState<AuthUser | null>(null);
  const [error, setError] = useState<unknown>(null);
  const [customState, setCustomState] = useState<string | null>(null);

  useEffect(() => {
    const unsubscribe = Hub.listen("auth", ({ payload }) => {
      switch (payload.event) {
        case "signInWithRedirect":
          console.log('it worked !')
          getUser();
          break;
        case "signInWithRedirect_failure":
          setError("An error has occurred during the OAuth flow.");
          break;
        case "customOAuthState":
          setCustomState(payload.data); // this is the customState provided on signInWithRedirect function
          console.log(customState)
          break;
      }
    });

    getUser();

    return unsubscribe;
  }, []);

  const getUser = async (): Promise<void> => {
    try {
      const currentUser = await getCurrentUser();
      setUser(currentUser);
      router.push('/');
    } catch (error) {
      console.error(error);
      console.log("Not signed in");
    }
  };

  return (
    <Box component="div" sx={{ mt: 3 }}>
      <Button variant="contained" onClick={() => signInWithRedirect({ provider, customState: "custom-state" })}>
        SSO Connexion
      </Button>
    </Box>
  )
}

export default SSOButton;

Log output

The only info I receive from the call is an `undefined` value that I print.

aws-exports.js

No response

Manual configuration

"Auth": {
    "Cognito": {
      "userPoolClientId": "userPoolClientId",
      "userPoolId": "userPoolId",
      "loginWith": {
          "oauth": {
            "domain": "dev-nbsm.auth.us-east-1.amazoncognito.com",
            "scopes": [ "phone", "email", "profile", "openid", "aws.cognito.signin.user.admin" ],
            "redirectSignIn": [ "http://localhost:3000/" ],
            "redirectSignOut": [ "http://localhost:3000/" ],
            "responseType": "code",
            "providers": [ { "custom": "custom-provider" } ]
          }
      }
    }
  }

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 6 months ago

Hey, @jojimcNova 👋. When you state that you're using a custom login page, is it a different URL than what is specified in your config (which is "http://localhost:3000/" it looks like)?

jojimcNova commented 6 months ago

Hi @cwomack, currently, I have the login page in the following url : http://localhost:3000/login. I use a middleware to redirect to /login if the user is not login. If he's authenticated, I redirect him to http://localhost:3000/

jojimcNova commented 6 months ago

I finally got it, I had an issue with the callbacks. I setup everything to point http://localhost:3000/login. Thank you for your support ! 😄