使用Nodemailer节点发送邮件的现代Oauth2身份验证

xxe27gdn  于 2022-11-21  发布在  其他
关注(0)|答案(3)|浏览(426)

我正在nodejs应用程序中使用nodemailer发送电子邮件。

var payload = { auth: 
               {
                user: smtpuser,
                pass: smtppass
               },
                to : toAddr,
                from  : emailfrom,
                cc : ccAddr,
                subject : subject,
                html    : content,
                attachments: attachments
              };

var transporter = nodemailer.createTransport(
                   { host: payload.host || 'smtp.office365.com', // Office 365 server
                     port: payload.port || 587,     // secure SMTP
                     secure:payload.secure || false, // false for TLS - as a boolean not string - but the default is false so just remove this completely
                     auth: payload.auth,
                     debug: true,
                     tls: payload.tls || {ciphers: 'SSLv3'}
                   });

transporter.sendMail(payload, function (error, info) {
                if (error) {
                    return console.log(error);
                }
                updateMessage(updatedMsg);
            });

我开始得到这个错误:
错误:登录无效:535 5.7.3验证失败[SN4PR0601CA0002.namprd06.prod.outlook.com]
看来我的团队已经禁用了基本身份验证。
我需要实现现代身份验证(Oauth2),以便能够使用outlook id通过nodemailer发送邮件。
有人对此有什么想法吗?这需要什么配置(代码)更改?

nimxete2

nimxete21#

在长时间探索如何使用OAuth2从服务器发送电子邮件之后,我以这个工作示例结束。
1.创建应用程序https://go.microsoft.com/fwlink/?linkid=2083908
1.在{您的APP管理面板}〉API权限〉添加权限〉Microsoft Graph〉应用程序权限〉邮件.发送〉添加权限中添加权限
1.创建证书以获取客户端密码{您的应用程序管理面板}〉证书和密码〉客户端密码〉新客户端密码(将“Value”字符串保存在您的client_secret位置)
1.确保已安装所需的节点应用程序
1.现在,您可以运行以下代码从服务器发送任何电子邮件:

const msal = require('@azure/msal-node');
    const fetch = require('node-fetch');

    const clientSecret = process.env.CLIENT_SECRET;
    const clientId = process.env.CLIENT_ID;
    const tenantId = process.env.TENANT_ID;
    const aadEndpoint =
      process.env.AAD_ENDPOINT || 'https://login.microsoftonline.com';
    const graphEndpoint =
      process.env.GRAPH_ENDPOINT || 'https://graph.microsoft.com';

    const msalConfig = {
      auth: {
        clientId,
        clientSecret,
        authority: aadEndpoint + '/' + tenantId,
      },
    };

    const tokenRequest = {
      scopes: [graphEndpoint + '/.default'],
    };

    const cca = new msal.ConfidentialClientApplication(msalConfig);
    const tokenInfo = await cca.acquireTokenByClientCredential(tokenRequest);

    const mail = {
      subject: 'Microsoft Graph JavaScript Sample',
      //This "from" is optional if you want to send from group email. For this you need to give permissions in that group to send emails from it.
      from: {
        emailAddress: {
          address: 'noreply@company.com',
        },
      },
      toRecipients: [
        {
          emailAddress: {
            address: 'someemail@domain.com',
          },
        },
      ],
      body: {
        content:
          '<h1>MicrosoftGraph JavaScript Sample</h1>This is the email body',
        contentType: 'html',
      },
    };

    const headers = new fetch.Headers();
    const bearer = `Bearer ${tokenInfo.accessToken}`;

    headers.append('Authorization', bearer);
    headers.append('Content-Type', 'application/json');

    const options = {
      method: 'POST',
      headers,
      body: JSON.stringify({ message: mail, saveToSentItems: false }),
    };

    await fetch(
      graphEndpoint + '/v1.0/users/youroutlookemail@company.com/sendMail',
      options
    );

也可以在此处查看电子邮件设置:
https://learn.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=javascript
可能它会帮助某人;)

dfty9e19

dfty9e192#

我建议你使用Microsoft Graph发送电子邮件。这里有一个简单易用的REST API,可以很好地与OAuth配合使用。
请在下面找到一些链接来帮助您快速构建。
https://learn.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=httphttps://learn.microsoft.com/en-us/graph/auth/auth-concepts?view=graph-rest-1.0https://learn.microsoft.com/en-us/graph/tutorials/node?view=graph-rest-1.0

4ioopgfo

4ioopgfo3#

# # SMTP 受到 限制 ( 适用 于 Office365 )

Microsoft is moving to discourage direct SMTP protocol access ( 无论 身份 验证 是 基本 的 还是 现代 的 ) , 特别 是 对于 自动 化 脚本/作业 。 建议 的 最 佳 做法 ( 对于 Office365 ) 是 停止 使用 SMTP 协议 , 而 使用 Microsoft Graph API 发送 电子 邮件 。

    • NodeMailer * * ( 截至 2022 年 10 月 ) 支持 SMTP 、 sendmail 和 SES 传输 - - 目前 还 不 支持 Microsoft Graph 传输 。 Feature Request(https://github.com/nodemailer/nodemailer/issues/1485) 。

# # 实施 :发送 电子 邮件 ( 通过 Microsoft Graph - 〉 sendMail

Javascript/Node10 + , 测试 日期 : 2022 年 11 月 。 大量 来源 于 * * Bogdan Le's answer * *

let tenantID = "" // Get from Azure App Registration
let oAuthClientID = "" // Get from Azure App Registration
let clientSecret = "" // Get from Azure App Registration
let oAuthToken; // declared, gets defined if successfully fetched

let userFrom = "foo@bar.com"
let msgPayload = { 
  //Ref: https://learn.microsoft.com/en-us/graph/api/resources/message#properties
  message: {
    subject: 'Test',
    body: {
      contentType: 'HTML',
      content: 'Test123'
    },
    toRecipients: [{emailAddress: {address: 'meganb@contoso.onmicrosoft.com'}}]
  }
};

const axios = require('axios'); //using axios as http helper
await axios({ // Get OAuth token to connect as OAuth client
  method: 'post',
  url: `https://login.microsoftonline.com/${tenantID}/oauth2/token`,
  data: new URLSearchParams({
    client_id: oAuthClientID,
    client_secret: clientSecret,
    resource: "https://graph.microsoft.com",
    grant_type: "client_credentials"
  }).toString()
})
.then(r => oAuthToken = r.data.access_token)

await axios ({ // Send Email using Microsoft Graph
  method: 'post',
  url: `https://graph.microsoft.com/v1.0/users/${userFrom}/sendMail`,
  headers: {
    'Authorization': "Bearer " + oAuthToken,
    'Content-Type': 'application/json'
  },
  data: msgPayload
})

中 的 每 一 个

    • 附录 1 :创建 用于 发送 电子 邮件 的 Azure oAuth 应用 * *

1.* * 建立 * * Azure App Registration
1.* * 添加 邮件 发送 权限 : * * Azure 应用 程序 注册 管理 〉 API 权限 〉 添加 权限 〉 Microsoft GraphApplication 权限 〉 Mail.Send

    • 警告 : * * 您 需要 使用 application access policy 将 应用 注册 的 访问 权限 限制 为 特定 邮箱 。 默认 情况 下 , 其 * 租户 范围 * - 允许 模拟 任何 用户 的 邮箱 !

1.* * 授予 管理 员 同意 * * 您 新 创建 的 Mail.Send 权限 ( 可能 需要 全局 管理 员 )

      • 创建 应用 程序 密码 : * * Azure 应用 程序 注册 管理 员 〉 证书 和 机密 〉 客户 端 机密 - 〉 新 客户 端 机密 ( 注意 生成 的 机密 )
  • 创建 提醒/计划 以 在 每个 过期 期 刷新 此 机密 ( 在 Azure 中 以及 您 自己 的 代码 中 )
    • 附录 二 :限制 Mail.Send 权限 * *

1.* * Office 365 管理 员 : * * 创建 启用 邮件 的 安全 组 ( 记下 组 名 )
1.* * 将 成员 添加 到 该组 : * * 添加 您 希望 应用 注册 能够 通过 Mail.Send 模拟 其 邮箱 的 用户 。
1.* * 通过 Powershell 创建 ( 并 测试 ) Application Access Policy * * :

##Variables - Manually define these:
$AppClientID="" #ClientID from Azure App Registration
$Group="" #Name of Office365 group
$ForbiddenMailbox="" #Address of mailbox AppRegistration should NOT have permission to
$AllowedMailbox="" #Address of mailbox AppRegistration should have permission to

##Connect to Exchange
Install-Module -Name ExchangeOnlineManagement 
Connect-ExchangeOnline 

##Create ApplicationAccessPolicy 
New-ApplicationAccessPolicy -AppId $AppClientID -PolicyScopeGroupId $Group -AccessRight RestrictAccess -Description "Limit AppRegistration mailbox permissions to subset of users"

##Test ApplicationAccessPolicy - Denied Scenario
Test-ApplicationAccessPolicy -Identity $ForbiddenMailbox -AppId $AppClientID

##Test ApplicationAccessPolicy - Granted Scenario
Test-ApplicationAccessPolicy -Identity $AllowedMailbox -AppId $AppClientID

格式

相关问题