Node.js Web アプリでアクセス トークンを取得する
適用対象: 従業員テナント 外部テナント (詳細情報)
この記事では、コードを更新して、Web アプリがアクセス トークンを取得できるようにします。 Node 用の Microsoft Authentication Library (MSAL) を使用して、ノード Web アプリケーションへの認証と承認の追加を簡略化します。 この記事は、4 部構成のガイド シリーズの第 3 部です。
前提条件
- このガイド シリーズの最初のパートである「Node.js Web アプリケーションで API を呼び出すための外部テナントを準備する」の手順を完了します。
- このガイド シリーズの第 2 部「Node.js Web アプリケーションで API を呼び出すアプリを準備する」の手順を完了します。
MSAL 構成オブジェクトを更新する
コード エディターで authConfig.js ファイルを開き、protectedResources
オブジェクトを追加してコードを更新します。
//..
const toDoListReadScope = process.env.TODOLIST_READ || 'api://Enter_the_Web_Api_Application_Id_Here/ToDoList.Read';
const toDoListReadWriteScope = process.env.TODOLIST_READWRITE || 'api://Enter_the_Web_Api_Application_Id_Here/ToDoList.ReadWrite';
const protectedResources = {
toDoListAPI: {
endpoint: 'https://localhost:44351/api/todolist',
scopes: {
read: [toDoListReadScope],
write: [toDoListReadWriteScope],
},
},
};
module.exports = {
//..
protectedResources,
//..
};
authConfig.js ファイルで、Enter_the_Web_Api_Application_Id_Here
を、顧客のテナントに登録した Web API アプリのアプリケーション (クライアント) ID に置き換えます。
todolistReadScope
変数と todolistReadWriteScope
変数は、外部テナントで設定した Web API の全範囲の URL を保持します。 必ず protectedResources
オブジェクトをエクスポートします。
アクセス トークンを取得する
コード エディターで、auth/AuthProvider.js ファイルを開き、AuthProvider
クラスの getToken
メソッドを更新します。
const axios = require('axios');
class AuthProvider {
//...
getToken(scopes) {
return async function (req, res, next) {
const msalInstance = authProvider.getMsalInstance(authProvider.config.msalConfig);
try {
msalInstance.getTokenCache().deserialize(req.session.tokenCache);
const silentRequest = {
account: req.session.account,
scopes: scopes,
};
const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest);
req.session.tokenCache = msalInstance.getTokenCache().serialize();
req.session.accessToken = tokenResponse.accessToken;
next();
} catch (error) {
if (error instanceof msal.InteractionRequiredAuthError) {
req.session.csrfToken = authProvider.cryptoProvider.createNewGuid();
const state = authProvider.cryptoProvider.base64Encode(
JSON.stringify({
redirectTo: 'http://localhost:3000/todos',
csrfToken: req.session.csrfToken,
})
);
const authCodeUrlRequestParams = {
state: state,
scopes: scopes,
};
const authCodeRequestParams = {
state: state,
scopes: scopes,
};
authProvider.redirectToAuthCodeUrl(
req,
res,
next,
authCodeUrlRequestParams,
authCodeRequestParams,
msalInstance
);
}
next(error);
}
};
}
//...
}
まず、この関数はアクセス トークンをサイレントに (ユーザーに資格情報の入力を求めずに) 取得しようとします。
const silentRequest = { account: req.session.account, scopes: scopes, }; const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest);
トークンをサイレントに正常に取得した場合は、それをセッションに格納します。 API を呼び出すときに、セッションからトークンを取得します。
req.session.accessToken = tokenResponse.accessToken;
トークンをサイレントに取得できない (
InteractionRequiredAuthError
例外などによる) 場合、アクセス トークンを新たに要求します。
Note
アクセス トークンを受け取ったクライアント アプリケーションは、それを不透明な文字列として処理する必要があります。 アクセス トークンは、クライアント アプリケーションではなく API を対象としています。 そのため、クライアント アプリケーションでは、アクセス トークンの読み取りまたは処理を試みるべきではありません。 そうではなく、アクセス トークンは、API への要求の Authorization ヘッダーにそのまま含める必要があります。 API は、アクセス トークンを解釈し、それを使用してクライアント アプリケーションの要求を認証および承認する役割を担います。