Search code examples
amazon-cognitoaws-amplify

Cognito '/oauth2/token' end point not returning 'id_token' for Authorization Code Grant with PKCE


Cognito '/oauth2/token' end point not returning 'id_token' for Authorization Code Grant with PKCE even though the documentation says it will be returned (Link). It should return the id_token as well. Is this normal or I need to configure more? I have added the content of the git issue opened by me below if this is helpful(Issue 7393)

To Reproduce Steps to reproduce the behavior:

  1. Configure the user pool with hosted UI support
  2. Go to hosted UI and complete the login
  3. User will be redirected to the "redirectSignIn" URL
  4. Hub.listen('auth') event fired with error message "Sign in failure Error: Username and Pool information are required."
  5. Check the session for ID token
  6. Check the code challenge request to get the tokens(/oauth2/token request)
  7. Both do not have the ID token. /oauth2/token only returns access_token, expires_in, refresh_token and token_type

Expected behavior It should also return id_token

Code Snippet

   import React, {useEffect, useState} from 'react';
   import { Amplify, Auth, Hub  } from 'aws-amplify';
   import {AmplifyConfig} from '../../config/amplifyConfig';
   Amplify.configure({
      Auth: AmplifyConfig.auth
   });
   const AuthorizePage = (props: any) => {
   const [user, setUser] = useState(null);
   useEffect(() => {
        Hub.listen('auth', ({ payload: { event, data } }) => {
        switch (event) {
            case 'signIn':
            case 'cognitoHostedUI':
                getUser().then(userData => setUser(userData));
                break;
            case 'signOut':
                setUser(null);
                break;
            case 'signIn_failure':
            case 'cognitoHostedUI_failure':
                console.log('Sign in failure', data);
                break;
        }
        });
    
        getUser().then(userData => setUser(userData));
    }, []);
    
    function getUser() {
        return Auth.currentAuthenticatedUser()
        .then(userData => userData)
        .catch(() => console.log('Not signed in'));
    }

    return (
        <div className="menu-card-filter--items" data-id="aperitif">
            <span>
                Authorizing
            </span>
        </div>
    )
}

export default AuthorizePage;

Screenshots

Request https://user-images.githubusercontent.com/12485276/101932415-bccab580-3c00-11eb-8cde-222d72f0d956.png

Response https://user-images.githubusercontent.com/12485276/101932467-d3710c80-3c00-11eb-9d3b-778faee43fa4.png

What is Configured?

  Auth: {
  mandatorySignIn: true,
  region: "******-*",
  userPoolId: "**-******-*_*******",
  userPoolWebClientId: "**********************",
  oauth: {
    domain: "**********************.amazoncognito.com",
    scope: [
      "phone",
      "email",
      "profile",
    ],
    redirectSignIn: "http://localhost:3000/authorize",
    redirectSignOut: "http://localhost:3000/logout",
    responseType: "code"
  }
}

Solution

  • Add the 'openid' scope to the scope list in your auth configuration.

    The openid scope returns all user attributes in the ID token that are readable by the client. The ID token is not returned if the openid scope is not requested by the client.

    https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-app-idp-settings.html here