您不能直接从 Azure App Service(原 Azure 网站)使用 SMTP 中继服务器(如 smtp.office365.com)来发送邮件。

azure 网站 邮件
(图片来源网络,侵删)

这是因为出于安全考虑,Azure 的出站网络连接默认是受限的,并且为了防止垃圾邮件,Microsoft 的 SMTP 服务器要求客户端连接必须进行身份验证,而 App Service 的出站连接通常无法满足这种严格的认证要求。

我们需要采用以下几种推荐的解决方案:


使用 SendGrid (最推荐、最简单)

这是 Microsoft 官方最推荐、与 Azure 集成最紧密的方案,SendGrid 是一个专业的云邮件服务,专门为开发者设计。

优点:

azure 网站 邮件
(图片来源网络,侵删)
  • 官方集成:在 Azure 门户中可以一键创建 SendGrid 资源,并直接在 App Service 中配置。
  • 高送达率:专业服务,确保邮件能顺利进入收件人收件箱,而不是垃圾邮件箱。
  • 可扩展性强:无论您是发送 100 封还是 1000 万封邮件,SendGrid 都能轻松应对。
  • 功能丰富:提供模板、统计、分析、邮件路由等高级功能。
  • 有免费套餐:新用户每月有 100 封免费邮件,非常适合开发和测试。

缺点:

  • 对于极少量、非关键性的邮件,可能感觉有些“重”。

操作步骤:

  1. 创建 SendGrid 资源

    • 登录 Azure 门户
    • 点击“创建资源”,搜索“SendGrid”并创建。
    • 选择免费套餐 (Free),创建资源。
  2. 获取 API 密钥

    azure 网站 邮件
    (图片来源网络,侵删)
    • 进入 SendGrid 资源管理页面。
    • 在左侧菜单选择“设置” -> “API 密钥”。
    • 点击“创建 API 密钥”,给它一个名字(AzureWebAppEmail),并选择权限(Full Access 即可)。
    • 重要! 复制生成的密钥并妥善保存,这个密钥只会显示一次!
  3. 在代码中使用 SendGrid

    • SendGrid 提供了多种语言的 SDK,使用起来非常方便。

    示例 (C#):

    // 安装 NuGet 包: SendGrid
    using SendGrid;
    using SendGrid.Helpers.Mail;
    public async Task SendEmailWithSendGrid()
    {
        // 从 Azure Key Vault 或 App Settings 中获取密钥,不要硬编码!
        var apiKey = Environment.GetEnvironmentVariable("SENDGRID_API_KEY");
        var client = new SendGridClient(apiKey);
        var from = new EmailAddress("noreply@yourdomain.com", "您的网站名称");
        var to = new EmailAddress("user@example.com", "用户姓名");
        var subject = "来自 Azure 网站的问候";
        var htmlContent = "<strong>这是一封通过 SendGrid 发送的测试邮件!</strong>";
        var msg = MailHelper.CreateSingleEmail(from, to, subject, null, htmlContent);
        var response = await client.SendEmailAsync(msg);
    }

    示例 (Node.js):

    // 安装 npm 包: @sendgrid/mail
    const sgMail = require('@sendgrid/mail');
    // 从环境变量中获取密钥
    sgMail.setApiKey(process.env.SENDGRID_API_KEY);
    const msg = {
      to: 'user@example.com', // 收件人
      from: 'noreply@yourdomain.com', // 必须是你在 SendGrid 上验证过的发件人
      subject: '来自 Azure 网站的问候',
      text: '这是一封通过 SendGrid 发送的测试邮件!',
      html: '<strong>这是一封通过 SendGrid 发送的测试邮件!</strong>',
    };
    sgMail.send(msg)
      .then(() => {
        console.log('邮件已发送');
      })
      .catch((error) => {
        console.error(error);
      });
  4. 安全存储密钥

    • 最佳实践:不要将 API 密钥直接写在代码里。
    • 在 App Service 的“配置” -> “应用程序设置”中,添加一个名为 SENDGRID_API_KEY 的设置,值为你的密钥。
    • 在代码中通过 Environment.GetEnvironmentVariable("SENDGRID_API_KEY") (C#) 或 process.env.SENDGRID_API_KEY (Node.js) 来读取。

使用 Azure Logic Apps (功能最强大、最灵活)

Logic Apps 是一个强大的自动化和集成服务,你可以用它来构建一个“当网站有新用户注册时,发送邮件”的工作流。

优点:

  • 无需编写代码:通过可视化的设计器拖拽即可创建工作流。
  • 集成能力极强:可以轻松连接到其他上百种服务和应用(如 SharePoint, SQL, Twitter 等)。
  • 逻辑复杂:可以实现非常复杂的业务逻辑,检查用户是否存在 -> 发送欢迎邮件 -> 如果失败则记录到日志”。
  • 免费额度:每月有 250,000 个操作免费额度,对于大多数邮件发送任务来说已经足够。

缺点:

  • 相比直接调用 SDK,设置步骤稍多。

操作步骤:

  1. 创建 Logic App

    • 在 Azure 门户中创建一个“逻辑应用”资源。
    • 选择“从空白模板开始”。
  2. 设计工作流

    • 在 Logic App 设计器中,首先选择一个触发器,对于从网站发送邮件,最常用的触发器是:
      • 当 HTTP 请求收到时:你的 App Service 可以调用一个 API 端点,触发 Logic App 发送邮件,这是最常用的方式。
      • 当 Azure 函数调用时:如果你的邮件发送逻辑是由 Azure Function 触发的,可以选择这个触发器。
  3. 添加操作

    • 在触发器之后,点击“+ 新建步骤”。
    • 搜索操作 Office 365 Outlook (如果你有 Office 365 订阅) 或 Out.com (如果你有个人 Outlook.com 账户)。
    • 选择操作“发送电子邮件 (V2)”。
    • 填写邮件信息:收件人、主题、正文等,你可以在正文中使用来自触发器(即 HTTP 请求)的数据。
  4. 调用 Logic App

    • 在你的网站代码中,使用 HTTP 客户端(如 HttpClient)调用 Logic App 生成的回调 URL,并传递必要的参数(如收件人邮箱、邮件内容等)。

使用第三方 SMTP 服务 (最通用)

如果你已经有其他喜欢的邮件服务(如 Mailgun, Amazon SES, Mandrill 等),你也可以使用它们。

优点:

  • 如果你已经在使用这些服务,可以无缝集成。
  • 功能和 SendGrid 类似,都是专业的邮件服务。

缺点:

  • 需要在 Azure App Service 中进行额外的网络配置(见下文)。

操作步骤:

  1. 在第三方服务商处获取 SMTP 服务器信息和密钥

  2. 配置 App Service 的出站网络

    • 这是关键一步!因为 App Service 默认会阻止 SMTP 端口(如 25, 587, 465)的出站连接。
    • 在 App Service 的“网络” -> “出站连接”中,添加一个规则。
    • 目标 FQDN 填写你的 SMTP 服务器地址(如 smtp.mailgun.org),目标端口填写 587 (或服务商指定的端口)。
    • 这样你的应用就可以连接到该 SMTP 服务器了。
  3. 在代码中使用标准 SMTP 客户端

    • 使用你所用语言的标准 SMTP 库来发送邮件。

    示例 (C#):

    using System.Net;
    using System.Net.Mail;
    using System.Threading.Tasks;
    public async Task SendEmailWithSmtp()
    {
        var smtpClient = new SmtpClient("smtp.your-service-provider.com")
        {
            Port = 587,
            Credentials = new NetworkCredential("your-smtp-username", "your-smtp-password"),
            EnableSsl = true,
        };
        var mailMessage = new MailMessage
        {
            From = new MailAddress("noreply@yourdomain.com"),
            Subject = "测试邮件",
            Body = "这是一封通过第三方 SMTP 服务发送的邮件。",
            IsBodyHtml = true,
        };
        mailMessage.To.Add("user@example.com");
        await smtpClient.SendMailAsync(mailMessage);
    }

如何选择?

方案 适用场景 优点 缺点
SendGrid 绝大多数场景,尤其是新项目,简单、快速、官方推荐。 集成最简单,送达率高,有免费额度。 非核心邮件功能可能显得“重”。
Logic Apps 需要复杂业务逻辑或集成多个系统的场景,用户注册 -> 发送邮件 -> 更新数据库 -> 发送 Slack 通知。 无需编码,可视化设计,集成能力极强。 设置相对复杂,不适合简单的“点对点”邮件发送。
第三方 SMTP 已有其他邮件服务账号,或对 SendGrid/Logic Apps 有特殊排斥的情况。 选择灵活,功能专业。 需要手动配置 App Service 出站网络,不如 SendGrid 集成完美。

总结与最佳实践

  1. 首选 SendGrid:对于 99% 的 Azure 网站发送邮件的需求,SendGrid 是最佳选择,它简单、可靠且与 Azure 生态完美结合。
  2. 永远不要硬编码密钥:使用 Azure App Service 的“应用程序设置”或更安全的 Azure Key Vault 来存储 API 密钥和密码。
  3. 选择合适的触发器:如果是用户触发的邮件(如注册、重置密码),在网站代码中直接调用 SendGrid SDK,如果是后台流程或需要复杂逻辑,使用 Logic Apps。
  4. 注意垃圾邮件:确保你的邮件内容不包含垃圾邮件关键词,并且你的域名有良好的发送信誉,使用 SendGrid 等专业服务能显著提高送达率。