Kurz: Přidání toků přihlašování a odhlášení do JavaScript SPA
V tomto kurzu nakonfigurujete jednostránkové aplikace JavaScriptu (SPA) pro ověřování. V 1. části této sériejste vytvořili JavaScript SPA a připravili ho na ověření. V tomto kurzu se dozvíte, jak přidat toky ověřování přidáním komponent knihovny MSAL (Microsoft Authentication Library) do vaší aplikace a vytvoření responzivního uživatelského rozhraní (UI) pro vaši aplikaci.
V tomto kurzu;
- Přidejte kód do auth.js pro zpracování procesu ověřování.
- Vytvoření uživatelského rozhraní pro aplikaci
Požadavky
Přidání kódu do souboru přesměrování
Tok ověřování je řada kroků, které aplikace provede k ověření uživatele. Auth.js obsahuje funkce, které slouží ke zpracování procesu ověřování, včetně přihlášení a odhlášení pomocí metody vyskakovacího okna nebo přesměrování.
Otevřete public/auth.js a přidejte následující kód:
// Browser check variables: If you support IE, our recommendation is to sign-in using Redirect APIs. If you are testing using Edge InPrivate mode, please add "isEdge" to the if check. const ua = window.navigator.userAgent; const msie = ua.indexOf("MSIE "); const msie11 = ua.indexOf("Trident/"); const msedge = ua.indexOf("Edge/"); const isIE = msie > 0 || msie11 > 0; const isEdge = msedge > 0; let signInType; let accountId = ""; // myMSALObj instance - configuration parameters are located at authConfig.js const myMSALObj = new msal.PublicClientApplication(msalConfig); myMSALObj.initialize().then(() => { // Redirect: once login is successful and redirects with tokens, call Graph API myMSALObj.handleRedirectPromise().then(handleResponse).catch(err => { console.error(err); }); }) 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 showWelcomeMessage(currentAccounts[0].username); updateTable(currentAccounts[0]); } } function handleResponse(resp) { if (resp !== null) { accountId = resp.account.homeAccountId; myMSALObj.setActiveAccount(resp.account); showWelcomeMessage(resp.account); } else { selectAccount(); } } async function signIn(method) { signInType = isIE ? "redirect" : method; if (signInType === "popup") { return myMSALObj.loginPopup({ ...loginRequest, redirectUri: "/redirect" }).then(handleResponse).catch(function (error) { console.log(error); }); } else if (signInType === "redirect") { return myMSALObj.loginRedirect(loginRequest) } } function signOut(interactionType) { const logoutRequest = { account: myMSALObj.getAccountByHomeId(accountId) }; if (interactionType === "popup") { myMSALObj.logoutPopup(logoutRequest).then(() => { window.location.reload(); }); } else { myMSALObj.logoutRedirect(logoutRequest); } } // This function can be removed if you do not need to support IE async function getTokenRedirect(request, account) { return await myMSALObj.acquireTokenSilent(request).catch(async (error) => { console.log("silent token acquisition fails."); if (error instanceof msal.InteractionRequiredAuthError) { // fallback to interaction when silent call fails console.log("acquiring token using redirect"); myMSALObj.acquireTokenRedirect(request); } else { console.error(error); } }); }
Uložte soubor.
Vytvoření uživatelského rozhraní pro aplikaci
Po nakonfigurování autorizace je možné vytvořit uživatelské rozhraní pro interakci s aplikací při spuštění projektu. Bootstrap se používá k vytvoření responzivního uživatelského rozhraní, které obsahuje tlačítko přihlášení a tlačítko odhlášení. Uživatelské rozhraní obsahuje také tabulku, která zobrazuje nároky z tokenu, které budou přidány později v tutoriálu.
Přidání kódu do souboru index.html
Hlavní stránka SPA, index.html, je první stránka, která se načte při spuštění aplikace. Je to také stránka, která se načte, když uživatel vybere tlačítko Odhlásit se. Stránka obsahuje navigační panel, uvítací zprávu s e-mailem uživatelů a tabulku, která zobrazuje deklarace identity z tokenu.
Otevřete public/index.html a přidejte následující fragment kódu:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no"> <title>Microsoft identity platform</title> <link rel="SHORTCUT ICON" href="./favicon.svg" type="image/x-icon"> <link rel="stylesheet" href="./styles.css"> <!-- adding Bootstrap 5 for UI components --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous"> <!-- msal.min.js can be used in the place of msal-browser.js --> <script src="/msal-browser.min.js"></script> </head> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Bootstrap 5 Navbar</title> <!-- Bootstrap 5 CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Rl3l94faQlfdS3b8SpxyDkgOn+Y5Qu3og6JpNZnN9LfX9k8wAI5" crossorigin="anonymous"> </head> <body> <!-- Navbar --> <nav class="navbar navbar-expand-sm navbar-dark bg-primary navbarStyle"> <a class="navbar-brand" href="/">Microsoft identity platform</a> <div class="ms-auto d-flex align-items-center"> <!-- Dropdown group (Bootstrap 5 uses dropstart instead of dropleft) --> <div class="btn-group dropstart"> <!-- Toggle button for dropdown --> <button id="signIn" type="button" class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" > Sign In </button> <!-- Dropdown menu --> <div class="dropdown-menu"> <button class="dropdown-item" id="popup" onclick="signIn(this.id)"> Sign in using Popup </button> <button class="dropdown-item" id="redirect" onclick="signIn(this.id)"> Sign in using Redirect </button> </div> </div> <!-- Sign Out button --> <button class="btn btn-secondary ms-2" id="signOut" onclick="signOut()"> Sign Out </button> </div> </nav> <br /> <div class="container"> <div class="row"> <h5 id="title-div" class="card-header text-center"> JavaScript single-page application secured with MSAL.js </h5> <br /> <h5 id="welcome-div" class="card-header text-center d-none"></h5> <table class="table table-striped table-bordered d-none" id="table-div"> <thead> <tr> <th>Claim Type</th> <th>Value</th> <th>Description</th> </tr> </thead> <tbody id="table-body-div"></tbody> </table> </div> </div> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"> </script> <!-- Bootstrap 5 JS bundle (includes Popper) --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"> </script> <!-- Your custom scripts --> <script type="text/javascript" src="./authConfig.js"></script> <script type="text/javascript" src="./ui.js"></script> <script type="text/javascript" src="./claimUtils.js"></script> <script type="text/javascript" src="./auth.js"></script> </body> </html>
Uložte soubor.
Přidání kódu do souboru ui.js
Aby byla vaše aplikace interaktivní, ui.js soubor slouží ke zpracování prvků uživatelského rozhraní aplikace. Soubor obsahuje funkce, které slouží k aktualizaci jména uživatele při přihlášení a aktualizaci tabulky deklaracemi identity z tokenu.
Otevřete public/ui.js a přidejte následující fragment kódu:
// Select DOM elements to work with const signInButton = document.getElementById('signIn'); const signOutButton = document.getElementById('signOut'); const titleDiv = document.getElementById('title-div'); const welcomeDiv = document.getElementById('welcome-div'); const tableDiv = document.getElementById('table-div'); const tableBody = document.getElementById('table-body-div'); function showWelcomeMessage(account) { signInButton.classList.add('d-none'); signOutButton.classList.remove('d-none'); titleDiv.classList.add('d-none'); welcomeDiv.classList.remove('d-none'); welcomeDiv.innerHTML = `Welcome ${account.username}!`; updateTable(account); }; function updateTable(account) { tableDiv.classList.remove('d-none'); const tokenClaims = createClaimsTable(account.idTokenClaims); Object.keys(tokenClaims).forEach((key) => { let row = tableBody.insertRow(0); let cell1 = row.insertCell(0); let cell2 = row.insertCell(1); let cell3 = row.insertCell(2); cell1.innerHTML = tokenClaims[key][0]; cell2.innerHTML = tokenClaims[key][1]; cell3.innerHTML = tokenClaims[key][2]; }); };
Uložte soubor.
Přidání kódu do souboru signout.html
Soubor signout.html slouží k zobrazení zprávy uživateli při odhlášení z aplikace.
Otevřete public/signout.html a přidejte následující fragment kódu:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Microsoft Entra ID | JavaScript SPA</title> <link rel="SHORTCUT ICON" href="./favicon.svg" type="image/x-icon"> <!-- adding Bootstrap 4 for UI components --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> </head> <body> <div class="jumbotron" style="margin: 10%"> <h1>Goodbye!</h1> <p>You have signed out and your cache has been cleared.</p> <a class="btn btn-primary" href="/" role="button">Take me back</a> </div> </body> </html>
Uložte soubor.
Přidání stylů do aplikace
Nakonec do aplikace přidejte některé styly, aby vypadala působivěji. Styly se přidají do souboru styles.css a dají se přizpůsobit tak, aby vyhovovaly vašim potřebám.
Otevřete public/styles.css a přidejte následující fragment kódu:
.navbarStyle { padding: .5rem 1rem !important; } .table-responsive-ms { max-height: 39rem !important; padding-left: 10%; padding-right: 10%; }
Uložte soubor.