チュートリアル: Vanilla JavaScript SPA で認証フローを処理する
このチュートリアルは、Vanilla JavaScript (JS) シングルページ アプリケーション (SPA) を構築して、認証のための準備をする方法を示すシリーズのパート 3 です。 このシリーズのパート 2 では、Vanilla JS SPA を作成し、外部テナントでの認証用に準備しました。 このチュートリアルでは、Microsoft Authentication Library (MSAL) コンポーネントを追加することで、アプリの認証フローを処理する方法について説明します。
このチュートリアルでは、
- アプリケーションの設定を構成する
- authRedirect.js にコードを追加して認証フローを処理する
- authPopup.js にコードを追加して認証フローを処理する
前提条件
認証構成ファイルを編集する
Public/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: [], };
次の値を、Azure portal の値に置き換えます。
Enter_the_Application_Id_Here
の値を見つけ、Microsoft Entra 管理センターで登録したアプリのアプリケーション ID (clientId) に置き換えます。- [権限] で、
Enter_the_Tenant_Subdomain_Here
を見つけ、それをテナントのサブドメインに置き換えます。 たとえば、テナントのプライマリ ドメインがcontoso.onmicrosoft.com
の場合は、contoso
を使用します。 テナント名がない場合は、テナントの詳細を読み取る方法を確認してください。
- [権限] で、
ファイルを保存します。
カスタム URL ドメインを使用する (省略可能)
カスタム ドメインを使用して、認証 URL を完全にブランド化します。 ユーザーの視点から見ると、認証プロセスの間、ユーザーは ciamlogin.com ドメイン名にリダイレクトされず、あなたのドメインにとどまります。
カスタム ドメインを使用するには、以下の手順を実行します。
「外部テナント内のアプリに対するカスタム URL ドメインの有効化」の手順を使用し、外部テナントに対してカスタム URL ドメインを有効にします。
authConfig.js ファイルで、
auth
オブジェクトを見つけて、次のようにします。authority
プロパティの値を https://Enter_the_Custom_Domain_Here/Enter_the_Tenant_ID_Here に更新します。Enter_the_Custom_Domain_Here
を実際のカスタム URL ドメインに、Enter_the_Tenant_ID_Here
を実際のテナント ID に置き換えます。 テナント ID がわからない場合は、テナントの詳細を読み取る方法を確認してください。- [Enter_the_Custom_Domain_Here] という値を持つ
knownAuthorities
プロパティを追加します。
authConfig.js ファイルを変更した後、カスタム URL ドメインが login.contoso.com で、テナント ID が 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 を呼び出すために使用されます。 また、認証プロセス中に発生するエラーを処理するためにも使用されます。
public/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); }
ファイルを保存します。
authPopup.js ファイルにコードを追加する
ユーザーがポップアップ ウィンドウを使用してサインインする場合、アプリケーションでは authPopup.js を使用して認証フローを処理します。 ポップアップ ウィンドウは、ユーザーが既にサインインしていて、アプリケーションで別のリソースのアクセス トークンを取得する必要がある場合に使用されます。
public/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();
ファイルを保存します。