教程:从 Node/Express.js Web 应用调用Microsoft图形 API

适用于带白色复选标记符号的绿色圆圈,指示以下内容适用于员工租户。 员工租户 绿色圆圈,带有白色复选标记符号,指示以下内容适用于外部租户。 外部租户(了解详细信息

在本教程中,你将从 Node/Express.js Web 应用调用 Microsoft 图形 API。 用户登录后,应用将获取访问令牌以调用Microsoft图形 API。

本教程是 3 部分教程系列的第 3 部分。

在本教程中,你将:

  • 更新 Node/Express.js Web 应用以获取访问令牌
  • 使用访问令牌调用 Microsoft Graph API。

先决条件

添加 UI 组件

  1. 在代码编辑器中,打开 views/index.hbs 文件,然后使用以下代码片段添加 视图用户配置文件 链接:

    <a href="/users/profile">View user profile</a>
    

    进行更新后, views/index.hbs 文件应类似于以下文件:

       <h1>{{title}}</h1>
        {{#if isAuthenticated }}
        <p>Hi {{username}}!</p>
        <a href="/users/id">View ID token claims</a>
        <br>
        <a href="/users/profile">View user profile</a>
        <br>
        <br>
        <a href="/auth/signout">Sign out</a>
        {{else}}
        <p>Welcome to {{title}}</p>
        <a href="/auth/signin">Sign in</a>
        {{/if}}
    
  2. 创建 views/profile.hbs 文件,然后添加以下代码:

    <h1>Microsoft Graph API</h1>
    <h3>/me endpoint response</h3>
    <table>
        <tbody>
            {{#each profile}}
            <tr>
                <td>{{@key}}</td>
                <td>{{this}}</td>
            </tr>
            {{/each}}
        </tbody>
    </table>
    <br>
    <a href="/">Go back</a>
    
    • 此页面显示 Microsoft Graph API 返回的用户个人资料详细信息。

获取访问令牌

在代码编辑器中,打开身份验证/AuthProvider.js 文件,然后在类中添加getTokenAuthProvider方法:

class AuthProvider {
    //...
        getToken(scopes, redirectUri = "http://localhost:3000/") {
            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: redirectUri,
                                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);
                }
            };
        }
}
    //...

该方法 getToken 使用指定的范围来获取访问令牌

添加调用 API 路由

在代码编辑器中,打开 路由/users.js 文件,然后添加以下路由:

router.get(
    "/profile",
    isAuthenticated,
    authProvider.getToken(["User.Read"]), // check if user is authenticated
    async function (req, res, next) {
    const graphResponse = await fetch(
        GRAPH_ME_ENDPOINT,
        req.session.accessToken,
    );
    if (!graphResponse.id) {
        return res 
        .status(501) 
        .send("Failed to fetch profile details"); 
    }
    res.render("profile", {
        profile: graphResponse,
    });
    },
);
  • 当客户用户选择/profile”链接时,将触发路由。 应用:

    • 获取具有 User.Read 权限的访问令牌。
    • 调用 Microsoft Graph API 来读取已登录用户的信息。
    • profile.hbs UI 中显示用户详细信息。

调用Microsoft图形 API

创建 fetch.js 文件,然后添加以下代码:

var axios = require('axios');
var authProvider = require("./auth/AuthProvider");

/**
 * Makes an Authorization "Bearer" request with the given accessToken to the given endpoint.
 * @param endpoint
 * @param accessToken
 * @param method
 */
const fetch = async (endpoint, accessToken, method = "GET", data = null) => {
    const options = {
        headers: {
            Authorization: `Bearer ${accessToken}`,
        },
    };

    console.log(`request made to ${endpoint} at: ` + new Date().toString());

    try{
        const response = await axios.get(endpoint, options);
        return await response.data;

    }catch(error){
        throw new Error(error);
    }

};

module.exports = { fetch };

实际 API 调用发生在 fetch.js 文件中。

运行并测试 Node/Express.js Web 应用

  1. 使用 运行和测试 Node/Express.js Web 应用 中的步骤来运行 Web 应用。
  2. 登录后,选择“ 查看用户配置文件 ”链接。 如果应用程序正常运行,您应该能够查看从 Microsoft Graph API 读取并显示的已登录用户的个人资料。