AxaFrance / oidc-client

Light, Secure, Pure Javascript OIDC (Open ID Connect) Client. We provide also a REACT wrapper (compatible NextJS, etc.).
MIT License
600 stars 161 forks source link

Is there any status to know if a user is logging out? #1456

Open mikibakaiki opened 1 month ago

mikibakaiki commented 1 month ago

Not an issue, more like asking for help :)

Is there any way to know if a user is logging out? I needed this kind of behavior, and i think this was possible using the react-oidc-context package. However, reading through the documentation and testing with a react demo, i couldn't find any status for this specific purposes.

From what i gather, there's only the OidcUserStatus enum.

Any hints? :)

EDIT: Meanwhile, found this, and it might be what i want, but how can i use it through oidc-react ?

guillaume-chervet commented 1 month ago

Hi @mikibakaiki , does the property isAuthenticated do the job for your use case ?

https://github.com/AxaFrance/oidc-client/blob/4f9ca8e903fc286f4d72ce069ad92873624ca2d3/examples/react-oidc-demo/src/Home.tsx#L13C39-L13C55

mikibakaiki commented 1 month ago

Hey @guillaume-chervet , thanks for quickly getting back to me :)

I'm still not sure. Going through a big code base, and don't know all the logic behind it 😅

The isAuthenticated is just a boolean, right?

How could i use the Status enum i mentioned?

Also, on the same project, it doesn't make sense to use both oidc-client and oidc-react, right?

guillaume-chervet commented 1 month ago

hi @mikibakaiki ,

yes isAuthenticated is just a boolean.

Status is an internal property for internal behavior.

You can listen events for this event : image

the way to listen events => https://github.com/AxaFrance/oidc-client/blob/7a3e1f07216fd9077cce9485a8591aad7a1215c7/examples/react-oidc-demo/src/App.tsx#L32

mikibakaiki commented 1 month ago

Thanks for answering, and sorry for taking too long to answer :) i got side tracked on this task.

Looking back at it, i think that the isAuthenticated might be a solution.

I have two questions, maybe a little of topic (one of them!):

  1. How would you listen for the concrete logout event, as you mention? I feel like there's a concrete event i should be listening to.

  2. I'm wondering if there's a type for the configuration object. I know in previous versions there was, because im updating a codebase that relied on the former oidc-client@1.11.5 😅 Now, in the the readme, i only see:

export const configuration = {
  client_id: 'interactive.public.short',
  redirect_uri: window.location.origin + '/#/authentication/callback',
  silent_redirect_uri: window.location.origin + '/#/authentication/silent-callback',
  scope: 'openid profile email api offline_access',
  authority: 'https://demo.duendesoftware.com',
  service_worker_relative_url: '/OidcServiceWorker.js', // just comment that line to disable service worker mode
  service_worker_only: false,
  demonstrating_proof_of_possession: false,
};

with no type association.

Trying to look into this, so i don't change much of the codebase's logic, and can comply with good software practices :)

This is the older code version, and what i was looking for:

// oidc-client/index.d.ts

export interface OidcClientSettings {
  /** The URL of the OIDC/OAuth2 provider */
  authority?: string;
  readonly metadataUrl?: string;
  /** Provide metadata when authority server does not allow CORS on the metadata endpoint */
  metadata?: Partial<OidcMetadata>;
  /** Provide signingKeys when authority server does not allow CORS on the jwks uri */
  signingKeys?: any[];
  /** Your client application's identifier as registered with the OIDC/OAuth2 */
  client_id?: string;
  client_secret?: string;
  /** The type of response desired from the OIDC/OAuth2 provider (default: 'id_token') */
  readonly response_type?: string;
  readonly response_mode?: string;
  /** The scope being requested from the OIDC/OAuth2 provider (default: 'openid') */
  readonly scope?: string;
  /** The redirect URI of your client application to receive a response from the OIDC/OAuth2 provider */
  readonly redirect_uri?: string;
  /** The OIDC/OAuth2 post-logout redirect URI */
  readonly post_logout_redirect_uri?: string;
  /** The OIDC/OAuth2 post-logout redirect URI when using popup */
  readonly popup_post_logout_redirect_uri?: string;
  readonly prompt?: string;
  readonly display?: string;
  readonly max_age?: number;
  readonly ui_locales?: string;
  readonly acr_values?: string;
  /** Should OIDC protocol claims be removed from profile (default: true) */
  readonly filterProtocolClaims?: boolean;
  /** Flag to control if additional identity data is loaded from the user info endpoint in order to populate the user's profile (default: true) */
  readonly loadUserInfo?: boolean;
  /** Number (in seconds) indicating the age of state entries in storage for authorize requests that are considered abandoned and thus can be cleaned up (default: 300) */
  readonly staleStateAge?: number;
  /** The window of time (in seconds) to allow the current time to deviate when validating id_token's iat, nbf, and exp values (default: 300) */
  readonly clockSkew?: number;
  readonly clockService?: ClockService;
  readonly stateStore?: StateStore;
  readonly userInfoJwtIssuer?: 'ANY' | 'OP' | string;
  readonly mergeClaims?: boolean;
  ResponseValidatorCtor?: ResponseValidatorCtor;
  MetadataServiceCtor?: MetadataServiceCtor;
  /** An object containing additional query string parameters to be including in the authorization request */
  extraQueryParams?: Record<string, any>;
}

export interface UserManagerSettings extends OidcClientSettings {
  /** The URL for the page containing the call to signinPopupCallback to handle the callback from the OIDC/OAuth2 */
  readonly popup_redirect_uri?: string;
  /** The features parameter to window.open for the popup signin window.
   *  default: 'location=no,toolbar=no,width=500,height=500,left=100,top=100'
   */
  readonly popupWindowFeatures?: string;
  /** The target parameter to window.open for the popup signin window (default: '_blank') */
  readonly popupWindowTarget?: any;
  /** The URL for the page containing the code handling the silent renew */
  readonly silent_redirect_uri?: any;
  /** Number of milliseconds to wait for the silent renew to return before assuming it has failed or timed out (default: 10000) */
  readonly silentRequestTimeout?: any;
  /** Flag to indicate if there should be an automatic attempt to renew the access token prior to its expiration (default: false) */
  readonly automaticSilentRenew?: boolean;
  readonly validateSubOnSilentRenew?: boolean;
  /** Flag to control if id_token is included as id_token_hint in silent renew calls (default: true) */
  readonly includeIdTokenInSilentRenew?: boolean;
  /** Will raise events for when user has performed a signout at the OP (default: true) */
  readonly monitorSession?: boolean;
  /** Interval, in ms, to check the user's session (default: 2000) */
  readonly checkSessionInterval?: number;
  readonly query_status_response_type?: string;
  readonly stopCheckSessionOnError?: boolean;
  /** Will invoke the revocation endpoint on signout if there is an access token for the user (default: false) */
  readonly revokeAccessTokenOnSignout?: boolean;
  /** The number of seconds before an access token is to expire to raise the accessTokenExpiring event (default: 60) */
  readonly accessTokenExpiringNotificationTime?: number;
  readonly redirectNavigator?: any;
  readonly popupNavigator?: any;
  readonly iframeNavigator?: any;
  /** Storage object used to persist User for currently authenticated user (default: session storage) */
  readonly userStore?: WebStorageStateStore;
}

I'm sure most of these things are deprecated. So if there's no specific type in the library, could you tell me the exact properties i would / might need, so i can create an interface :)

Thanks and sorry if it got out of topic, or too long and confused 😅

Have a great weekend!

jmc-debug commented 2 weeks ago

I think i managed to have everything working like i wanted :) thanks for the help and support, you can close the ticket!

Keep up the good work @guillaume-chervet 👏