几天来,我一直在努力实现一个功能,用户可以使用他们的outlook电子邮件进行身份验证,并安排发送电子邮件。因此,API应该能够代表经过身份验证的用户发送电子邮件。
身份验证流程正常工作,我能够保存访问令牌。Graphme调用也按预期工作。我用用户数据得到了预期的响应。
问题是当我试图发送电子邮件时。我得到以下错误:
{"statusCode":401,"code":null,"requestId":null,"date":"2023-04-21T14:18:46.748Z","body":{"_writeState":{"0":0,"1":0},"_readableState":{"objectMode":false,"highWaterMark":16384,"buffer":{"head":null,"tail":null,"length":0},"length":0,"pipes":null,"pipesCount":0,"flowing":null,"ended":false,"endEmitted":false,"reading":false,"sync":false,"needReadable":false,"emittedReadable":false,"readableListening":false,"resumeScheduled":false,"emitClose":true,"autoDestroy":false,"destroyed":false,"defaultEncoding":"utf8","awaitDrainWriters":null,"multiAwaitDrain":false,"readingMore":false,"decoder":null,"encoding":null},"readable":true,"_events":{"error":[null,null]},"_eventsCount":6,"_writableState":{"objectMode":false,"highWaterMark":16384,"finalCalled":false,"needDrain":false,"ending":false,"ended":false,"finished":false,"destroyed":false,"decodeStrings":true,"defaultEncoding":"utf8","length":10,"writing":true,"corked":0,"sync":false,"bufferProcessing":false,"writelen":10,"afterWriteTickInfo":null,"bufferedRequest":null,"lastBufferedRequest":null,"pendingcb":1,"prefinished":false,"errorEmitted":false,"emitClose":true,"autoDestroy":false,"bufferedRequestCount":0,"corkedRequestsFree":{"next":null,"entry":null}},"writable":true,"allowHalfOpen":true,"_transformState":{"needTransform":false,"transforming":true,"writechunk":{"type":"Buffer","data":[31,139,8,0,0,0,0,0,4,10]},"writeencoding":"buffer"},"_hadError":false,"bytesWritten":0,"_handle":{"buffer":{"type":"Buffer","data":[31,139,8,0,0,0,0,0,4,10]},"availOutBefore":16384,"availInBefore":10,"inOff":0,"flushFlag":2},"_outBuffer":{"type":"Buffer","data":[85,85,85,85,85,85,80,0,0,0,0,0,0,0]},"_outOffset":0,"_chunkSize":16384,"_defaultFlushFlag":2,"_finishFlushFlag":2,"_defaultFullFlushFlag":3,"_maxOutputLength":2147483647,"_level":-1,"_strategy":0}}
我认为我没有使用正确的权限,但我已经尝试了许多(所有注解的权限),仍然得到相同的错误消息。我别无选择了。
你们知道这里可能会出什么问题吗?
先谢谢你了
我使用了以下代码来验证用户并发送电子邮件:
import * as msal from "@azure/msal-node";
import { Client } from "@microsoft/microsoft-graph-client";
export const msalConfig: msal.Configuration = {
auth: {
clientId: “CLIENT_ID”,
authority: "https://login.microsoftonline.com/TENENT_ID”,
clientSecret: “CLIENT_SECRET”,
},
};
export const cca = new msal.ConfidentialClientApplication(msalConfig);
export const getGraphClient = (accessToken: string | null) => {
const graphClient = Client.init({
authProvider: (done) => {
done(null, accessToken);
},
});
return graphClient;
};
export const protectedResources = {
graphMe: {
meEndpoint: "https://graph.microsoft.com/v1.0/me",
usersEndpoint: "https://graph.microsoft.com/v1.0/users/",
scopes: [
"openid",
"profile",
"user.read",
"mail.send",
"offline_access",
// "Mail.Send",
// "https://graph.microsoft.com/.default",
// "https://graph.microsoft.com/Mail.Send.Shared",
// "https://graph.microsoft.com/Mail.Read",
// "https://graph.microsoft.com/profile",
// "https://graph.microsoft.com/.default",
// "https://outlook.office.com/IMAP.AccessAsUser.All",
],
},
};
// Code to start the authentication flow
const state = request.query.state as string;
try {
// Get the authorization URL
const authCodeUrlParameters: msal.AuthorizationUrlRequest = {
scopes: protectedResources.graphMe.scopes,
redirectUri: "https://example.com/outlookOauth2Callback",
codeChallengeMethod: "S256",
state: state,
};
const authorizeUrl = await cca.getAuthCodeUrl(authCodeUrlParameters);
response.redirect(authorizeUrl);
return;
} catch (error) {
console.log(error);
response.status(500).send(error);
return;
}
// Code to get the access Token
const code = request.query.code as string;
const state = request.query.state as string;
try {
const tokenRequest: msal.AuthorizationCodeRequest = {
code: code,
scopes: protectedResources.graphMe.scopes,
redirectUri:
"https://example.com/outlookOauth2Callback",
codeVerifier: request.query.code_verifier as string,
};
const accessToken = await cca.acquireTokenByCode(tokenRequest);
await saveUserToken(code, accessToken);
console.log("Successfully authorized");
response.redirect("https://example.com/callback.html?code=" + code + "&state=" + state);
return;
} catch (error) {
console.log(error);
response.status(500).send(error);
return;
}
// Code to send the email
const graphUser = await getGraphClient(token.accessToken)
.api(protectedResources.graphMe.meEndpoint)
.get();
functions.logger.log("Graph User: " + JSON.stringify(graphUser));
const message = {
subject: subject,
body: {
contentType: "HTML",
content: body,
},
toRecipients: [
{
emailAddress: {
toName: toName,
address: toEmail,
},
},
],
from: { emailAddress: { fromName: fromName, address: graphUser.email } },
};
const response = await getGraphClient(token[1].accessToken)
.api(protectedResources.graphMe.usersEndpoint + `${graphUser.id}/sendMail`)
.post({ message });
functions.logger.log("Response: " + JSON.stringify(response));
2条答案
按热度按时间2wnc66cl1#
若要代表使用Microsoft Graph的用户发送电子邮件,应用程序需要获得必要的委派权限。这些权限包括:
要添加这些权限,您需要转到Azure门户-〉应用程序注册-〉您的应用程序-〉API权限并添加这些权限。此外,您需要获取具有适当作用域的访问令牌以进行API调用。
lnlaulya2#
因为送了米亚“米亚。发送”权限就足够了,如文档中所述。
发送邮件:
检查您的访问令牌here并查看是否存在必要的权限。
有关更多信息,请参阅: www.example.com