如何从 Node 脚本获取 Microsoft Graph API 访问令牌?

How to get Microsoft Graph API Access token from Node Script?

我想使用这个库与我的广告的图形 API 进行交互 - https://github.com/microsoftgraph/microsoft-graph-docs/blob/master/concepts/nodejs.md

但是,我发现所有现有的 javascript 库 return 访问令牌都希望传入 return URL,还有一些其他特定于网络的东西,让我相信这是微软的某种要求。

有什么好的方法可以 authenticate/receive 访问令牌,同时 运行 后端节点脚本(与 Web 无关),以便我可以开始对 Microsoft Graph 进行调用 API?预先感谢您的建议。

运行 back-end non-user-authenticated 守护程序连接到图形 API,您想要使用 app-only 身份验证流程。这是 the official steps 的快速摘要:

  1. 创建您的 Azure AD 租户。记下 yourtenant.onmicrosoft.com 名称,并将此值复制下来。
  2. 通过全局 Azure Active Directory blade 的 App Registrations 部分注册应用程序,而不是直接在租户属性中。复制 Application ID;我们稍后会需要它。
  3. 创建绑定注册的密钥,记得复制下来。一旦点击退出,就无法取回键值,所以一定要复制。
  4. 同时将注册的权限更新为您需要的权限,单击 Save,然后还点击 Grant Permissions 按钮。
  5. login.microsoftonline.com 域发出 HTTP 请求以获取访问令牌。
  6. 使用访问令牌发出 Graph API 请求。

Here's a link to Microsofts Node.js example, and here's a link to the direct documentation 在 HTTP 调用上检索访问令牌。这是一个超级 stripped-down 示例,它将输出检索到的访问令牌。替换 [Tenant][ApplicationID][Key] 值:

const request = require("request");

const endpoint = "https://login.microsoftonline.com/[Tenant].onmicrosoft.com/oauth2/token";
const requestParams = {
    grant_type: "client_credentials",
    client_id: "[ApplicationID]",
    client_secret: "[Key]",
    resource: "https://graph.windows.net"
};

request.post({ url:endpoint, form: requestParams }, function (err, response, body) {
    if (err) {
        console.log("error");
    }
    else {
        console.log("Body=" + body);
        let parsedBody = JSON.parse(body);         
        if (parsedBody.error_description) {
            console.log("Error=" + parsedBody.error_description);
        }
        else {
            console.log("Access Token=" + parsedBody.access_token);
        }
    }
});

一旦我们有了 access_token,我们就可以调用图表 API。假设应用权限已正确配置并从第 4 步开始应用,我们可以开始制作 Graph API 请求:

function testGraphAPI(accessToken) {
    request.get({
        url:"https://graph.windows.net/[Tenant]/users?api-version=1.6",
        headers: {
          "Authorization": accessToken
        }
    }, function(err, response, body) {
        console.log(body);
    });
}

BU0's answer didn't work correctly for me because Microsoft changed their way of using the graph API so I wasn't able to get all the data I needed. Here's how I did it using BU0 answer and this tutorial:

const request = require("request");

const endpoint = "https://login.microsoftonline.com/[Tenant]/oauth2/v2.0/token";
const requestParams = {
    grant_type: "client_credentials",
    client_id: "[ApplicationID]",
    client_secret: "[Key]",
    scope: "https://graph.microsoft.com/.default"
};

request.post({ url: endpoint, form: requestParams }, function (err, response, body) {
    if (err) {
        console.log("error");
    }
    else {
        console.log("Body=" + body);
        let parsedBody = JSON.parse(body);
        if (parsedBody.error_description) {
            console.log("Error=" + parsedBody.error_description);
        }
        else {
            console.log("Access Token=" + parsedBody.access_token);
        }
    }
});

function testGraphAPI(accessToken) {
    request.get({
        url:"https://graph.microsoft.com/v1.0/users",
        headers: {
          "Authorization": "Bearer " + accessToken
        }
    }, function(err, response, body) {
        console.log(body);
    });
}

我在使用 url 字符串作为 const 端点时遇到了一些问题

https://login.microsoftonline.com/[Tenant]/oauth2/v2.0/token

相反,我通过 Microsoft graph api 文档以这种方式传递租户:

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize

来自文档的参考 -> Request an authorization code

另一种方式:

'use strict';

const axios = require('axios');
const qs = require('qs');

const accessTokenWithCredentials = (tenantId, clientId, clientSecret, resource) => {
    const data = {
        resource: resource,
        grant_type: 'client_credentials',

    };
    
    return axios({
        url: `https://login.windows.net/${tenantId}/oauth2/token`,
        method: "post",
        headers: { 'content-type': 'application/x-www-form-urlencoded' },
        auth: {
        username: clientId,
        password: clientSecret,
        },
        data:  qs.stringify(data)
    }).catch(error => {
        throw error;
    })
};

调用函数:

accessTokenWithCredentials(<tenantId>, <clientId>, <clientSecret>, 'https://graph.microsoft.com').then(response => {
    console.log(`Got access token`);
    const token = JSON.stringify(response.data.access_token);

    // do what you need to do

}).catch(err => {
     console.log("err " + err);
     throw err;
});