MSAL ノードでトークンを取得する

MSAL Node ではさまざまな承認コード許可がサポートされているため、許可ごとに異なるパブリック API とそれに対応する要求がサポートされます。 この記事では、フローごとに使用できるさまざまなパブリック API と、対応する要求の種類について説明します。 アプリケーションの承認コード フローを実装することを強くお勧めします。

認証コード フロー

パブリック API

  • getAuthCodeUrl(): この API は、MSAL ノードの authorization code grant の最初の区間です。 要求は AuthorizationUrlRequest 型です。 アプリケーションには、 authorization codeの生成に使用できる URL が送信されます。 この URL は任意のブラウザーで開くことができ、そこでユーザーは認証情報を入力すると、アプリの登録時に登録された redirectUriauthorization code 付きでリダイレクトされます。 authorization codeは、次の手順でtokenに引き換えることができます。 パブリック クライアント アプリケーションに対して承認コード フローが実行されている場合は、 PKCE をお勧めします。

  • acquireTokenByCode(): この API は、MSAL ノードの authorization code grant の第 2 段階です。 ここで構築される要求は、 AuthorizationCodeRequest 型である必要があります。 アプリケーションは、上記の手順の一環として受信した authorization code を渡し、 tokenと交換しました。 パブリック クライアント アプリケーションに対して承認コード フローが実行されている場合は、PKCE をお勧めします。


    const authCodeUrlParameters = {
        scopes: ["sample_scope"],
        redirectUri: "your_redirect_uri",
    };

    // get url to sign user in and consent to scopes needed for application
    cca.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
        console.log(response);
    }).catch((error) => console.log(JSON.stringify(error)));

    const tokenRequest = {
        code: "authorization_code",
        redirectUri: "your_redirect_uri",
        scopes: ["sample_scope"],
    };

    // acquire a token by exchanging the code
    cca.acquireTokenByCode(tokenRequest).then((response) => {
        console.log("\nResponse: \n:", response);
    }).catch((error) => {
        console.log(error);
    });

デバイス コード フロー

パブリック API

  • acquireTokenByDeviceCode(): この API を使用すると、アプリケーションはデバイス コードの付与を使用してトークンを取得できます。 要求の種類は DeviceCodeRequest です。 この API は、OAuth 2.0 のデバイス コード フローを使用して認証局から token を取得します。 このフローは、ブラウザーにアクセスできない、または入力の制約があるデバイス向けに設計されています。 承認サーバーは、検証コード、エンドユーザー コード、およびエンド ユーザー検証 URI を使用して DeviceCode オブジェクトを発行します。 DeviceCode オブジェクトはコールバックを通じて提供され、エンドユーザーは別のデバイスを使用して検証 URI に移動して資格情報を入力するように指示する必要があります。 クライアントは受信要求を受信できないため、エンド ユーザーが資格情報の入力を完了するまで、承認サーバーを繰り返しポーリングします。
const msalConfig = {
    auth: {
        clientId: "your_client_id_here",
        authority: "your_authority_here",
    }
};

const pca = new msal.PublicClientApplication(msalConfig);

const deviceCodeRequest = {
    deviceCodeCallback: (response) => (console.log(response.message)),
    scopes: ["user.read"],
};

pca.acquireTokenByDeviceCode(deviceCodeRequest).then((response) => {
    console.log(JSON.stringify(response));
}).catch((error) => {
    console.log(JSON.stringify(error));
});

リフレッシュ トークン フロー

パブリック API

  • acquireTokenByRefreshToken: この API は、新しいトークン セットに提供された更新トークンを交換することによってトークンを取得します。 要求の種類は RefreshTokenRequest ですrefresh tokenは応答でユーザーに返されることはありませんが、ユーザー キャッシュからアクセスできます。 非対話型のシナリオでは、 acquireTokenSilent() を使用することをお勧めします。 acquireTokenSilent()を使用する場合、MSAL はトークンのキャッシュと更新を自動的に処理します。
const config = {
    auth: {
        clientId: "your_client_id_here",
        authority: "your_authority_here",
    }
};

const pca = new msal.PublicClientApplication(config);

const refreshTokenRequest = {
    refreshToken: "",
    scopes: ["user.read"],
};

pca.acquireTokenByRefreshToken(refreshTokenRequest).then((response) => {
    console.log(JSON.stringify(response));
}).catch((error) => {
    console.log(JSON.stringify(error));
});

サイレント フロー

パブリック API

  • acquireTokenSilent: この API は、ユーザーによってキャッシュが提供された場合、またはキャッシュが作成された場合に、他の対話型フロー (承認コード フローなど) でこの呼び出しの前にトークンを取得します。 要求の種類は SilentFlowRequest ですtokenは、トークンが要求されるアカウントをユーザーが指定すると、自動的に取得されます。
/**
 * Cache Plugin configuration
 */
const cachePath = "path_to_your_cache_file/msal_cache.json"; // Replace this string with the path to your valid cache file.

const readFromStorage = () => {
    return fs.readFile(cachePath, "utf-8");
};

const writeToStorage = (getMergedState) => {
    return readFromStorage().then(oldFile =>{
        const mergedState = getMergedState(oldFile);
        return fs.writeFile(cachePath, mergedState);
    })
};

const cachePlugin = {
    readFromStorage,
    writeToStorage
};

/**
 * Public Client Application Configuration
 */
const publicClientConfig = {
    auth: {
        clientId: "your_client_id_here",
        authority: "your_authority_here",
        redirectUri: "your_redirectUri_here",
    },
    cache: {
        cachePlugin
    },
};

/** Request Configuration */

const scopes = ["your_scopes"];

const authCodeUrlParameters = {
    scopes: scopes,
    redirectUri: "your_redirectUri_here",
};

const pca = new msal.PublicClientApplication(publicClientConfig);
const msalCacheManager = pca.getCacheManager();
let accounts;

pca.getAuthCodeUrl(authCodeUrlParameters)
    .then((response) => {
        console.log(response);
    }).catch((error) => console.log(JSON.stringify(error)));

const tokenRequest = {
    code: req.query.code,
    redirectUri: "http://localhost:3000/redirect",
    scopes: scopes,
};

pca.acquireTokenByCode(tokenRequest).then((response) => {
    console.log("\nResponse: \n:", response);
    return msalCacheManager.writeToPersistence();
}).catch((error) => {
    console.log(error);
});

// get Accounts
accounts = msalCacheManager.getAllAccounts();

// Build silent request
const silentRequest = {
    account: accounts[0], // You would filter accounts to get the account you want to get tokens for
    scopes: scopes,
};

// Acquire Token Silently to be used in MS Graph call
pca.acquireTokenSilent(silentRequest).then((response) => {
    console.log("\nSuccessful silent token acquisition:\nResponse: \n:", response);
    return msalCacheManager.writeToPersistence();
}).catch((error) => {
        console.log(error);
});

クライアント資格情報フロー

パブリック API

  • acquireTokenByClientCredential: この API は、別の Web サービスを呼び出すときに(ユーザーを偽装するのではなく) 認証するために、機密クライアント アプリケーションの資格情報を使用してトークンを取得します。 このシナリオでは、通常、クライアントは中間層 Web サービス、デーモン サービス、またはバックエンド Web アプリケーションです。 高いレベルの保証では、Microsoft ID プラットフォームにより、呼び出し元サービスが、資格情報として (共有シークレットではなく) 証明書を使用することもできます。 要求の種類は ClientCredentialRequest です

シークレットを安全に使用する

シークレットはハードコーディングしないでください。 dotenv npm パッケージを使用すると、シークレットを .gitignore に含める必要がある .env ファイル (プロジェクトのルート ディレクトリにあります) にシークレットを格納し、シークレットが誤ってアップロードされるのを防ぐことができます。

import "dotenv/config"; // process.env now has the values defined in a .env file

const config = {
    auth: {
        clientId: "your_client_id_here",
        authority: "your_authority_here",
        clientSecret: process.env.clientSecret
    }
};

// Create msal application object
const cca = new msal.ConfidentialClientApplication(config);

// With client credentials flows permissions need to be granted in the portal by a tenant administrator.
// The scope is always in the format "<resource>/.default"
const clientCredentialRequest = {
    scopes: ["https://graph.microsoft.com/.default"], // replace with your resource
};

cca.acquireTokenByClientCredential(clientCredentialRequest).then((response) => {
    console.log("Response: ", response);
}).catch((error) => {
    console.log(JSON.stringify(error));
});

Flow に代わって

  • acquireTokenOnBehalfOf: この API は、On Behalf Of Flow を実装します。これは、アプリケーションがサービス/Web API を呼び出すときに使用されます。これは、他の認証フロー (デバイス コード、ユーザー名、パスワードなど) を使用する別のサービス/Web API を呼び出す必要があります。 アクセス トークンは最初に Web API によって取得されます (Web API フローのいずれかによって)。Web API は、OBO を介してこのトークンを別のトークンと交換できます。 要求は OnBehalfOfRequest 型です

使用方法については、On Behalf Of フローの サンプル を参照してください。

  • WebAPI サンプル コード
  • WebApp サンプル コード