我正试图创建一个从AWS lambda运行的应用程序,该应用程序作为中间人,为希望使用Microsoft Bookings注册预订的客户提供服务。根据文档,我能够为Graph生成一个访问令牌,但当我试图通过api从bookings中请求信息时,我得到了一个授权拒绝。
我的代码。
import request from "request";
import { Callback } from "./callback";
const APP_ID = process.env.BOOKINGS_APP_ID;
const APP_SECRET = process.env.BOOKINGS_API_SECRET;
const TOKEN_ENDPOINT = `https://login.microsoftonline.com/${process.env.BOOKINGS_TENANT_NAME}.onmicrosoft.com/oauth2/token`;
const requestParams = {
client_id: APP_ID,
client_secret: APP_SECRET,
grant_type: "client_credentials",
resource: "https://graph.microsoft.com",
scope: "https://graph.microsoft.com/.default",
};
export default class Bookings {
public static async listBusinesses(callback: Callback) {
Bookings.generateAPIToken((err: string | null, data: any) => {
const options = {
// body: {},
headers: {
"Authorization": `Bearer ${data}`,
"Content-Type": "application/json",
},
method: "GET",
url: "https://graph.microsoft.com/beta/bookingBusinesses",
};
console.log(data);
return request(options, (error: string, res: any) => {
if (error) {
return callback(error, {});
}
return callback(null, JSON.parse(res.body));
});
});
}
public static async generateAPIToken(callback: Callback) {
request.post({ url: TOKEN_ENDPOINT, form: requestParams }, (err, res, body) => {
if (err) {
return callback(err, {});
}
return callback(null, JSON.parse(body).access_token);
});
}
}
我得到的错误:
{
error: {
code: '',
message: 'Authorization has been denied for this request.',
innerError: {
'request-id': '695d3f90-357d-490c-b980-4a2018dd39a5',
date: '2020-06-08T03:21:59'
}
}
}
我也试过使用microsoft -graph -client库来访问预订,但也没有用。我做错了什么?谢谢你的帮助。
我们可以看到 文件 显示你要请求的图API(bookingBusinesses)需要委托类型权限,不支持应用类型权限。
所以我们不能使用 "client_credentials "授权流,你的代码显示你使用 "client_credentials "作为授权类型。你可以使用 "usernamepassword "授予流来代替获取访问令牌。所以,你请求的访问令牌的参数应该像下面这样。
const requestParams = {
client_id: APP_ID,
client_secret: APP_SECRET,
grant_type: "password",
scope: "https://graph.microsoft.com/.default",
username: "your user name/email(like [email protected])",
password: "your password"
};
对了,我注意到你代码中的 "TOKEN_DPOINT "是: https://login.microsoftonline.com/${process.env.BOOKINGS_TENANT_NAME}.onmicrosoft.com/oauth2/token
而你同时使用两个参数 resource
和 scope
在 requestParams
. 如果我们使用v1端点作为你的代码,我们只需要使用param------。resource
. 如果我们使用v2 endpoint(https://login.microsoftonline.com/${process.env.BOOKINGS_TENANT_NAME}.onmicrosoft.com/oauth2/v2.0/token
),我们需要使用使用param scope
而不是param resource
. 我上面提供的代码使用v2,所以我使用了 scope
param,并且你还需要将 "TOKEN_DPOINT "改为v2(只需添加一个 v2.0
之间 oauth2/
和 /token
).
如果你不想把 "TOKEN_DPOINT "改成v2,就用下面的params。
const requestParams = {
client_id: APP_ID,
client_secret: APP_SECRET,
grant_type: "password",
resource: "https://graph.microsoft.com",
username: "your user name/email(like [email protected])",
password: "your password"
};
希望对你有帮助