分享方式:


教學課程:處理 Vanilla JavaScript SPA 中的驗證流程

本教學課程是一系列的第 3 部分,示範如何建置 Vanilla JavaScript (JS) 單頁應用程式 (SPA),並準備進行驗證。 在此 系列的第 2 部分中,您已建立 Vanilla JS SPA,並準備好向外部租用戶進行驗證。 在本教學課程中,您將瞭解如何藉由新增Microsoft驗證連結庫 (MSAL) 元件來處理應用程式中的驗證流程。

在本教學課程中:

  • 設定應用程式設定
  • 將程式代碼新增至 authRedirect.js 以處理驗證流程
  • 將程式代碼新增至 authPopup.js 以處理驗證流程

必要條件

編輯驗證組態檔

應用程式會使用 隱含授與流程 來驗證使用者。 隱含授與流程是以瀏覽器為基礎的流程,不需要後端伺服器。 流程會將使用者重新導向至登入頁面,讓使用者登入並同意應用程式所要求的許可權。 authConfig.js的目的是設定驗證流程。

  1. 開啟 公用/authConfig.js ,並新增下列代碼段:

    import { LogLevel } from '@azure/msal-browser';
    
    /**
    * Configuration object to be passed to MSAL instance on creation. 
    * For a full list of MSAL.js configuration parameters, visit:
    * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/configuration.md 
    */
    
    export const msalConfig = {
        auth: {
            clientId: 'Enter_the_Application_Id_Here', // This is the ONLY mandatory field that you need to supply.
            authority: 'https://Enter_the_Tenant_Subdomain_Here.ciamlogin.com/', // Replace the placeholder with your tenant subdomain 
            redirectUri: '/', // Points to window.location.origin. You must register this URI on Azure Portal/App Registration.
            postLogoutRedirectUri: '/', // Indicates the page to navigate after logout.
            navigateToLoginRequestUrl: false, // If "true", will navigate back to the original request location before processing the auth code response.
        },
        cache: {
            cacheLocation: 'sessionStorage', // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs.
            storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
        },
        system: {
            loggerOptions: {
                loggerCallback: (level, message, containsPii) => {
                    if (containsPii) {
                        return;
                    }
                    switch (level) {
                        case LogLevel.Error:
                            console.error(message);
                            return;
                        case LogLevel.Info:
                            console.info(message);
                            return;
                        case LogLevel.Verbose:
                            console.debug(message);
                            return;
                        case LogLevel.Warning:
                            console.warn(message);
                            return;
                        default:
                            return;
                    }
                },
            },
        },
    };
    
    /**
    * Scopes you add here will be prompted for user consent during sign-in.
    * By default, MSAL.js will add OIDC scopes (openid, profile, email) to any login request.
    * For more information about OIDC scopes, visit: 
    * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#openid-connect-scopes
    */
    export const loginRequest = {
        scopes: [],
    };
    
  2. 將下列值取代為來自 Azure 入口網站的值:

    • 尋找 Enter_the_Application_Id_Here 值,並將其取代為您在 Microsoft Entra 系統管理中心所註冊應用程式的 應用程式識別碼 (clientId)
      • [授權單位] 中,尋找 Enter_the_Tenant_Subdomain_Here 並將它取代為您的租用戶的子域。 例如,如果您的租用戶主要網域是 contoso.onmicrosoft.com,請使用 contoso。 如果您沒有租用戶名稱,請了解如何讀取租用戶詳細資料
  3. 儲存檔案。

使用自訂網域 URL (選擇性 )

使用自定義網域來完整品牌驗證 URL。 從用戶的觀點來看,用戶在驗證程序期間會保留在網域上,而不是重新導向至 ciamlogin.com 功能變數名稱。

使用下列步驟來使用自訂網域:

  1. 使用為外部租使用者中的應用程式啟用自定義 URL 網域中的步驟,為您的外部租使用者啟用自定義網域 URL。

  2. 在您的 authConfig.js 檔案中,找出 then auth object,然後:

    1. 將屬性的值 authority 更新為 https://Enter_the_Custom_Domain_Here/Enter_the_Tenant_ID_HereEnter_the_Custom_Domain_Here取代為您的自訂網域 URL,並以Enter_the_Tenant_ID_Here您的租使用者識別碼取代 。 如果您沒有租使用者標識碼,請瞭解如何 閱讀您的租使用者詳細數據
    2. 新增 knownAuthorities 具有值 [Enter_the_Custom_Domain_Here] 的屬性。

對authConfig.js檔案進行變更之後,如果您的自定義網域 URL 已 login.contoso.com,且您的租用戶標識符為 aaaabbbb-0000-cccc-1111-dddd2222eeee,則您的檔案看起來應該類似下列代碼段:

//...
const msalConfig = {
    auth: {
        authority: process.env.AUTHORITY || 'https://login.contoso.com/aaaabbbb-0000-cccc-1111-dddd2222eeee', 
        knownAuthorities: ["login.contoso.com"],
        //Other properties
    },
    //...
};

將程式代碼新增至重新導向檔案

需要重新導向檔案,才能處理來自登入頁面的回應。 它用來從 URL 片段擷取存取令牌,並用它來呼叫受保護的 API。 它也可用來處理驗證程式期間發生的錯誤。

  1. 開啟 公用/authRedirect.js ,並新增下列代碼段:

    // Create the main myMSALObj instance
    // configuration parameters are located at authConfig.js
    const myMSALObj = new msal.PublicClientApplication(msalConfig);
    
    let username = "";
    
    /**
    * A promise handler needs to be registered for handling the
    * response returned from redirect flow. For more information, visit:
    * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/initialization.md#redirect-apis
    */
    myMSALObj.handleRedirectPromise()
        .then(handleResponse)
        .catch((error) => {
            console.error(error);
        });
    
    function selectAccount() {
    
        /**
        * See here for more info on account retrieval: 
        * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
        */
    
        const currentAccounts = myMSALObj.getAllAccounts();
    
        if (!currentAccounts) {
            return;
        } else if (currentAccounts.length > 1) {
            // Add your account choosing logic here
            console.warn("Multiple accounts detected.");
        } else if (currentAccounts.length === 1) {
            username = currentAccounts[0].username
            welcomeUser(currentAccounts[0].username);
            updateTable(currentAccounts[0]);
        }
    }
    
    function handleResponse(response) {
    
        /**
        * To see the full list of response object properties, visit:
        * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#response
        */
    
        if (response !== null) {
            username = response.account.username
            welcomeUser(username);
            updateTable(response.account);
        } else {
            selectAccount();
    
        }
    }
    
    function signIn() {
    
        /**
        * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
        * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
        */
    
        myMSALObj.loginRedirect(loginRequest);
    }
    
    function signOut() {
    
        /**
        * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
        * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
        */
    
        // Choose which account to logout from by passing a username.
        const logoutRequest = {
            account: myMSALObj.getAccountByUsername(username),
            postLogoutRedirectUri: '/signout', // remove this line if you would like navigate to index page after logout.
    
        };
    
        myMSALObj.logoutRedirect(logoutRequest);
    }
    
  2. 儲存檔案。

將程式代碼新增至 authPopup.js 檔案

當使用者使用彈出視窗登入時,應用程式會使用 authPopup.js 來處理驗證流程。 當用戶已經登入,而且應用程式需要取得不同資源的存取令牌時,就會使用彈出視窗。

  1. 開啟 公用/authPopup.js ,並新增下列代碼段:

    // Create the main myMSALObj instance
    // configuration parameters are located at authConfig.js
    const myMSALObj = new msal.PublicClientApplication(msalConfig);
    
    let username = "";
    
    function selectAccount () {
    
        /**
         * See here for more info on account retrieval: 
         * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md
         */
    
        const currentAccounts = myMSALObj.getAllAccounts();
    
        if (!currentAccounts  || currentAccounts.length < 1) {
            return;
        } else if (currentAccounts.length > 1) {
            // Add your account choosing logic here
            console.warn("Multiple accounts detected.");
        } else if (currentAccounts.length === 1) {
            username = currentAccounts[0].username
            welcomeUser(currentAccounts[0].username);
            updateTable(currentAccounts[0]);
        }
    }
    
    function handleResponse(response) {
    
        /**
         * To see the full list of response object properties, visit:
         * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#response
         */
    
        if (response !== null) {
            username = response.account.username
            welcomeUser(username);
            updateTable(response.account);
        } else {
            selectAccount();
        }
    }
    
    function signIn() {
    
        /**
         * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
         * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
         */
    
        myMSALObj.loginPopup(loginRequest)
            .then(handleResponse)
            .catch(error => {
                console.error(error);
            });
    }
    
    function signOut() {
    
        /**
         * You can pass a custom request object below. This will override the initial configuration. For more information, visit:
         * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request
         */
    
        // Choose which account to logout from by passing a username.
        const logoutRequest = {
            account: myMSALObj.getAccountByUsername(username),
            mainWindowRedirectUri: '/signout'
        };
    
        myMSALObj.logoutPopup(logoutRequest);
    }
    
    selectAccount();
    
  2. 儲存檔案。

後續步驟