チュートリアル: Node.js Web アプリケーションに追加のサインインとサインアウトを追加する
このチュートリアルは、Node.js Web アプリの構築と、Microsoft Entra 管理センターを使用した認証の準備を行うシリーズの最終パートです。 このシリーズのパート 2 では、Node.js Web アプリを作成し、必要なすべてのファイルを整理しました。 このチュートリアルでは、Node.js Web アプリへのサインイン、サインアップ、サインアウトを追加します。 Node.js Web アプリへの認証の追加を簡略化するには、Node 用 Microsoft Authentication Library (MSAL) を使用します。 サインイン フローでは、ユーザーを安全にサインインする OpenID Connect (OIDC) 認証プロトコルが使用されます。
このチュートリアルでは、次のことについて説明します。
- サインインロジックとサインアウトロジックを追加する
- ID トークン要求を表示する
- アプリを実行し、サインインとサインアウトのエクスペリエンスをテストします。
前提条件
- 「チュートリアル: Node.js Web アプリケーションを認証用に準備する」 の手順を完了しました。
MSAL 構成オブジェクトを作成する
コード エディターで authConfig.js ファイルを開き、次のコードを追加します。
require('dotenv').config();
const TENANT_SUBDOMAIN = process.env.TENANT_SUBDOMAIN || 'Enter_the_Tenant_Subdomain_Here';
const REDIRECT_URI = process.env.REDIRECT_URI || 'http://localhost:3000/auth/redirect';
const POST_LOGOUT_REDIRECT_URI = process.env.POST_LOGOUT_REDIRECT_URI || 'http://localhost:3000';
/**
* Configuration object to be passed to MSAL instance on creation.
* For a full list of MSAL Node configuration parameters, visit:
* https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/configuration.md
*/
const msalConfig = {
auth: {
clientId: process.env.CLIENT_ID || 'Enter_the_Application_Id_Here', // 'Application (client) ID' of app registration in Azure portal - this value is a GUID
authority: process.env.AUTHORITY || `https://${TENANT_SUBDOMAIN}.ciamlogin.com/`, // replace "Enter_the_Tenant_Subdomain_Here" with your tenant name
clientSecret: process.env.CLIENT_SECRET || 'Enter_the_Client_Secret_Here', // Client secret generated from the app registration in Azure portal
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log(message);
},
piiLoggingEnabled: false,
logLevel: 'Info',
},
},
};
module.exports = {
msalConfig,
REDIRECT_URI,
POST_LOGOUT_REDIRECT_URI,
TENANT_SUBDOMAIN
};
msalConfig
オブジェクトには、認証フローの動作をカスタマイズするために使用する一連の構成オプションが含まれています。
authConfig.js ファイルで、次を置き換えます。
Enter_the_Application_Id_Here
を、前に登録したアプリのアプリケーション (クライアント) ID に置き換えます。Enter_the_Tenant_Subdomain_Here
を、ディレクトリ (テナント) サブドメインに置き換えます。 たとえば、テナントのプライマリ ドメインがcontoso.onmicrosoft.com
の場合は、contoso
を使用します。 テナント名がない場合は、テナントの詳細を読み取る方法を確認してください。Enter_the_Client_Secret_Here
を、前にコピーしたアプリ シークレットの値に置き換えます。
.env ファイルを使用して構成情報を格納する場合:
コード エディターで .env ファイルを開き、次のコードを追加します。
CLIENT_ID=Enter_the_Application_Id_Here TENANT_SUBDOMAIN=Enter_the_Tenant_Subdomain_Here CLIENT_SECRET=Enter_the_Client_Secret_Here REDIRECT_URI=http://localhost:3000/auth/redirect POST_LOGOUT_REDIRECT_URI=http://localhost:3000
Enter_the_Application_Id_Here
、Enter_the_Tenant_Subdomain_Here
、Enter_the_Client_Secret_Here
の各プレースホルダーを、上記の説明に沿って置き換えます。
authConfig.js ファイル内の変数msalConfig
、REDIRECT_URI
、TENANT_SUBDOMAIN
、POST_LOGOUT_REDIRECT_URI
変数をエクスポートすると、ファイルが必要な場所でアクセスできるようになります。
カスタム 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
},
//...
};
Express Route を追加する
Express Route は、サインイン、サインアウト、ID トークン クレームの表示などの操作を実行できるようにするエンドポイントを提供します。
アプリのエントリ ポイント
コード エディターで "routes/index.js" ファイルを開き、次のコードを追加します。
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
res.render('index', {
title: 'MSAL Node & Express Web App',
isAuthenticated: req.session.isAuthenticated,
username: req.session.account?.username !== '' ? req.session.account?.username : req.session.account?.name,
});
});
module.exports = router;
/
ルートは、アプリケーションへのエントリ ポイントです。 「アプリ UI コンポーネントをビルドする」で作成した views/index.hbs ビューがレンダリングされます。 isAuthenticated
は、ビューに表示される内容を決定するブール変数です。
サインインとサインアウト
コード エディターで routes/auth.js ファイルを開き、auth.js からコードを追加します。
コード エディターで "controller/authController.js "ファイルを開き、それに authController.js からコードを追加します。
コード エディターで、"auth/AuthProvider.js" ファイルを開き、それに AuthProvider.js からコードを追加します。
/signin
、/signout
、および/redirect
ルートは routes/auth.js ファイルで定義されますが、そのロジックは auth/AuthProvider.js ファイルで実装します。
login
メソッドにより、次のように/signin
ルートが処理されます。認証コード フローの最初の区間がトリガーされ、サインイン フローが開始されます。
前に作成した MSAL 構成オブジェクト
msalConfig
を使用して、機密クライアント アプリケーション インスタンスが初期化されます。const msalInstance = this.getMsalInstance(this.config.msalConfig);
getMsalInstance
メソッドは次のように定義されます。getMsalInstance(msalConfig) { return new msal.ConfidentialClientApplication(msalConfig); }
承認コード フローの最初の区間で承認コード要求 URL を生成し、その URL にリダイレクトして承認コードを取得します。 この最初の区間は、
redirectToAuthCodeUrl
メソッドで実装されます。 ここでは、次のように MSAL の getAuthCodeUrl メソッドを使用して承認コード URL を生成しています。//... const authCodeUrlResponse = await msalInstance.getAuthCodeUrl(req.session.authCodeUrlRequest); //...
次に、承認コード URL 自体にリダイレクトします。
//... res.redirect(authCodeUrlResponse); //...
handleRedirect
メソッドは、次のように/redirect
ルートを処理します。これは、前に「Web アプリを登録する」 で Microsoft Entra 管理センター内の Web アプリのリダイレクト URI として設定したものです。
このエンドポイントは、認証コード フローで使用する 2 番めの区間を実装します。 これは、認証コードを使用し、MSAL の acquireTokenByCode メソッドを使用して ID トークンを要求します。
//... const tokenResponse = await msalInstance.acquireTokenByCode(authCodeRequest, req.body); //...
応答を受け取ったら、Express セッションを作成し、必要な任意の情報をそこに格納できます。
isAuthenticated
を含め、それをtrue
に設定する必要があります。//... req.session.idToken = tokenResponse.idToken; req.session.account = tokenResponse.account; req.session.isAuthenticated = true; //...
logout
メソッドにより、次のように/signout
ルートが処理されます。async logout(req, res, next) { /** * Construct a logout URI and redirect the user to end the * session with Azure AD. For more information, visit: * https://docs.microsoft.com/azure/active-directory/develop/v2-protocols-oidc#send-a-sign-out-request */ const logoutUri = `${this.config.msalConfig.auth.authority}${TENANT_SUBDOMAIN}.onmicrosoft.com/oauth2/v2.0/logout?post_logout_redirect_uri=${this.config.postLogoutRedirectUri}`; req.session.destroy(() => { res.redirect(logoutUri); }); }
サインアウト要求が開始されます。
ユーザーをアプリケーションからサインアウトさせる場合、ユーザーのセッションを終了するだけでは処理不足です。 ユーザーを logoutUri にリダイレクトする必要があります。 そうしないと、ユーザーは資格情報を再入力しなくても、アプリケーションに対して再認証できてしまう可能性があります。 テナントの名前が contoso の場合、logoutUri は
https://contoso.ciamlogin.com/contoso.onmicrosoft.com/oauth2/v2.0/logout?post_logout_redirect_uri=http://localhost:3000
のようになります。
ID トークン要求を表示する
コード エディターで routes/users.js ファイルを開き、次のコードを追加します。
const express = require('express');
const router = express.Router();
// custom middleware to check auth state
function isAuthenticated(req, res, next) {
if (!req.session.isAuthenticated) {
return res.redirect('/auth/signin'); // redirect to sign-in route
}
next();
};
router.get('/id',
isAuthenticated, // check if user is authenticated
async function (req, res, next) {
res.render('id', { idTokenClaims: req.session.account.idTokenClaims });
}
);
module.exports = router;
ユーザーが認証されている場合、/id
ルートに、views/id.hbs ビューを使用して ID トークン要求が表示されます。 このビューは、「アプリ UI コンポーネントをビルドする」で追加したものです。
given name などの特定の ID トークン要求を抽出するには:
const givenName = req.session.account.idTokenClaims.given_name
Web アプリを仕上げる
コード エディターで app.js ファイル開き、app.js からコードを追加します。
コード エディターで server.js ファイル開き、server.js からコードを追加します。
コード エディターで package.json ファイルを開き、
scripts
プロパティを次のように更新します。"scripts": { "start": "node server.js" }
Web アプリを実行してテストする
ターミナルで、
ciam-sign-in-node-express-web-app
などの Web アプリを含むプロジェクト フォルダーに移動します。ご利用のターミナルで、次のコマンドを実行します。
npm start
ブラウザーを開き、
http://localhost:3000
に移動します。 以下のスクリーンショットのようなページが表示されます。ページの読み込みが完了したら、[サインイン] リンクを選択します。 サインインするように求められます。
サインイン ページで、[メール アドレス] を入力して [次へ] を選択し、[パスワード] を入力してから [サインイン] を選択します。 アカウントをお持ちでない場合は、[アカウントをお持ちではない場合、作成できます] リンクを選択します。これで、サインアップ フローが開始されます。
サインアップ オプションを選択した場合は、メール、ワンタイム パスコード、新しいパスワード、その他のアカウントの詳細を入力すると、サインアップ フロー全体が完了します。 以下のスクリーンショットのようなページが表示されます。 サインイン オプションを選択すると、同様のページが表示されます。
[サインアウト] を選択して Web アプリからユーザーをサインアウトするか、ID トークン要求を表示する を選択して すべての ID トークン要求を表示します。