oidc-client-ts
                                
                                
                                
                                    oidc-client-ts copied to clipboard
                            
                            
                            
                        AWS Cognito logout endpoint
I am trying to implement sign-out against an AWS Cognito user pool.
I followed some of the hints here https://github.com/authts/oidc-client-ts/issues/802
const cognito = "xxxxxxxx";
const userPool = "xxxxxxxxxxxxx";
const clientId = "xxxxxxxxxxxxxxxxx";
const redirectUri = "http://localhost:3000";
const logoutUri = "http://localhost:3000";
const authorizationEndpoint = `https://${cognito}.auth.eu-west-2.amazoncognito.com/oauth2/authorize?response_type=code&client_id=${encodeURIComponent(clientId)}&redirect_uri=${encodeURIComponent(redirectUri)}`;
const endSessionEndpoint = `https://${cognito}.auth.eu-west-2.amazoncognito.com/logout?client_id=${encodeURIComponent(clientId)}&logout_uri=${encodeURIComponent(logoutUri)}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code`;
const userManager = new UserManager({
  authority: `https://cognito-idp.us-east-1.amazonaws.com/${userPool}`,
  client_id: clientId,
  redirect_uri: "http://localhost:3000",
  metadata: {
    authorization_endpoint: authorizationEndpoint,
    end_session_endpoint: endSessionEndpoint,
    revocation_endpoint: `https://${cognito}.auth.us-east-1.amazoncognito.com/oauth2/revoke`,
  },
  // no revoke of "access token" (https://github.com/authts/oidc-client-ts/issues/262)
  revokeTokenTypes: [ "refresh_token" ],
  // no silent renew via "prompt=none" (https://github.com/authts/oidc-client-ts/issues/366)
  automaticSilentRenew: false,
});
However, when I call userManager.signoutRedirect(), I get sent to the login screen hosted by AWS Cognito.
If I ignore the screen and navigate to http://localhost:3000/, then I find that I am still signed in (userManager.getUser() resolves to a user).
I can get sign-out like behaviour by calling userManager.removeUser() instead, but this seems wrong.
- Will the 
removeUserapproach lead to issues? - How should 
oidc-client-tsbe configured to work with the Cognito logout endpoint? 
You will need to configure the post_logout_redirect_uri in your oidc application and on IDP side, this and a valid session will make the IDP to call back into your application. In that callback you can call mgr.signoutCallback and navigate where you want.
Thanks, I followed those steps and was able to make progress.
However, it still seems to not actually sign-out.
Here is the sign-out logic:
  if (window.document.location.pathname === "/logout") {
    console.log("signoutCallback...");
    await userManager.signoutCallback();
    console.log("signoutCallback done.");
    const maybeUser = await userManager.getUser();
    const hasUser = !!maybeUser;
    console.log({ maybeUser });
  }
And the output:
signoutCallback...
signoutCallback done.
[UserManager] getUser: user loaded
Object { hasUser: true }
Is it expected that getUser will return a user after the signoutCallback has completed?
Is it expected that
getUserwill return a user after thesignoutCallbackhas completed?
No after the signout process its expected, that you have no user. You will need to debug that. BTW: Which version of this library do you have? 3.0.0 is here different compared to 2.4.0....
Is it expected that
getUserwill return a user after thesignoutCallbackhas completed?No after the signout process its expected, that you have no user. You will need to debug that. BTW: Which version of this library do you have? 3.0.0 is here different compared to 2.4.0....
Sorry, I should have specified.
oidc-client-ts@^3.0.0:
  version "3.0.0"
  resolved "https://registry.yarnpkg.com/oidc-client-ts/-/oidc-client-ts-3.0.0.tgz#910b27193b54730dbabd93709ca000f8b1e5bdf2"
  integrity sha512-YUcel/+C4AmXXhM/geNWc1jBsBVYzd+xhvSl1NMkxKpzZXqhLKmtj1ttSdxtDYm3P2YelnAr4zS4c96+p02iFQ==
  dependencies:
    jwt-decode "^4.0.0"
Looking at the source-code, it seems like it silently returns when there is no state in the URL.
AWS Cognito (somewhat strangely) does not pass any state back from the logout callback, so perhaps this is the issue?
I may be that Cognito is not a fully compliant endpoint, but given its popularity I am hoping that people have found work-arounds.
according to https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html the logout endpoint expects a client_id and a logout_uri query parameters.
I managed to get logout working by adding extra query params:
    userManager.signoutRedirect({
      extraQueryParams: {
        client_id: userManager.settings.client_id,
        logout_uri: 'http://localhost:1234/logout-callback'
      }
    })
If you specify a redirect_uri/response_type instead the user will be asked to re-login before going back to your application with a token. This flow (calling signoutRedirect and receiving a new token in signoutCallback) is unexpected, I guess the lib will happily gobble the new token and sign in the user again?