node.js - 使用 Nodemailer nodejs 发送邮件的现代 Oauth2 身份验证

标签 node.js oauth-2.0 nodemailer exchange-basicauth

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

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);
            });

我开始收到此错误:

Error: Invalid log in: 535 5.7.3 Authentication unsuccessful [SN4PR0601CA0002.namprd06.prod.outlook.com]

我的团队现在似乎已禁用基本身份验证。

我需要实现现代身份验证(Oauth2)才能使用 Outlook ID 通过 nodemailer 发送邮件。

有人对此有任何想法吗? 这需要什么配置(代码)更改?

最佳答案

经过长时间探索如何使用 OAuth2 从服务器发送电子邮件,我最终得到了这个工作示例。

  1. 创建应用 https://go.microsoft.com/fwlink/?linkid=2083908
  2. 在 {您的应用管理面板} > API 权限 > 添加权限 > Microsoft Graph > 应用程序权限 > Mail.Send > 添加权限中添加权限
  3. 创建证书以获取客户端 key {您的应用管理面板} > 证书和 key > 客户端 key > 新客户端 key (将“Value”字符串保存在您的 client_secret 中)
  4. 确保您已安装所需的 Node 应用
  5. 现在您可以运行此代码从您的服务器发送任何电子邮件:
    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

也许它会对某人有所帮助;)

关于node.js - 使用 Nodemailer nodejs 发送邮件的现代 Oauth2 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58322118/

相关文章:

node.js - Django vs Node(Express) vs Flask 用于具有高安全性和实时性的 RESTful API

javascript - 下载的文件会保存两次吗?

oauth-2.0 - WSO2 API Manager 客户端凭据更新 token

node.js - 调用函数后运行的 if 语句

javascript - 需要帮助让我的 Nodemailer 正常工作

node.js - 如何在 Sequelize 中使用 between 运算符?

node.js - 声明合并和别名不能一起工作

node.js - 是否可以在nodemailer中动态设置发件人地址?

javascript - 使用自定义 header 重定向到外部站点 - AngularJS/OAuth

oauth-2.0 - 使用 Microsoft 帐户 (login.live.com) 在 Azure AD B2C 上使用 MSAL.js acquireTokenSilent