Pop-up Window Authentication Configuration

To configure the Pop-up Window Authentication login format, one would need to use the OpenID Connect Client of TypeScript.

The OpenID Connect Client contains a class with the name of UserManager, which provides a higher level API for signing a user in, signing out, managing the user's claims return from the OpenID Connect Provider, and managing an access token returned from the OpenID Connect/OAuth2.0 Provider.

To make the configuration one would need to use two (2) authentication methods that the UserManager class contains, first one is an asynchronous method called signinPopup which returns promise to trigger a request (via a popup window) to the authorization endpoint. The result of the promise is the authenticated "User".

Then, one would need to notify the opening window of response from the authorization endpoint. This would need to be done with the second asynchronous method which is called signinPopupCallback which returns promise to notify the opening window of response from the authorization endpoint.

An example on how to configure the pop-up window authentication on a React Application.

First one would need to import the oidc-client library which contains the UserManager class:

  import { UserManager } from "oidc-react";

And then, the UserManager instance should contain a couple of properties which are as following:

  export const userManager = new UserManager({
  userStore: new WebStorageStateStore({ store: localStorage }),
  authority: process.env.REACT_APP_AUTHORITY,
  client_id: process.env.REACT_APP_CLIENT_ID,
  client_secret: process.env.REACT_APP_SECRET,
  response_type: "code",
  redirect_uri: process.env.REACT_APP_URL,
  post_logout_redirect_uri: process.env.REACT_APP_URL,
  popup_redirect_uri: process.env.REACT_APP_URL,
  scope: process.env.REACT_APP_SCOPE,
  automaticSilentRenew: true,
  silent_redirect_uri: process.env.REACT_APP_URL,
  popupWindowFeatures: "width=550,height=700,left=50,top=0",
});

The configuration would need to be done on the button where the login function is called.

We need to handle the login functionality where we retrieve the user data and sign the user in:

    const handleLogin = () => {
    userManager
      .signinPopup()
      .then((data) => {
        console.log("User Data", data)
      })
      .catch((e) => {
        console.log("err:", e);
      });
  };

Then, create a function to close the pop-up window:

    const handlePopupCallback = () => {
    return userManager
        .signinPopupCallback(window.location.href.split("?")[1])
        .catch((error) => console.log("Popup callback failed:" + error));
    };

Then, we call the above function after the component is rendered:

    useEffect(() => {
    handlePopupCallback();
  }, []);

And last we need to return the component:

    return (
    <div>
        <h3>Handle Login with window popup</h3>
        <button onClick={handleLogin} className="btn-primary">
          Login
        </button>
    </div>
  )
}

The final result should look something like this:

  import React, {useEffect} from 'react'

export const Example = () => {
       
  const handleLogin = () => {
    userManager
      .signinPopup()
      .then((data) => {
        console.log("User Data", data)
      })
      .catch((e) => {
        console.log("err:", e);
      });
  };

  const handlePopupCallback = () => {
    return userManager
        .signinPopupCallback(window.location.href.split("?")[1])
        .catch((error) => console.log("Popup callback failed:" + error));
    };

  useEffect(() => {
    handlePopupCallback();
  }, []);

  return (
    <div>
        <h3>Handle Login with window popup</h3>
        <button onClick={handleLogin} className="btn-primary">
          Login
        </button>
    </div>
  )
}