10.3 在生产环境中发送邮件

我们已经成功实现了账户激活和密码重设功能,本节要配置应用,让它在生产环境中能真正地发送邮件。我们首先搭建一个免费的邮件服务,然后配置应用,最后再部署。

我们要在生产环境中使用 SendGrid 服务发送邮件。这个服务是 Heroku 的扩展,只有通过认证的账户才能使用。(要在 Heroku 的账户中填写信用卡信息,不过认证不收费。)对我们的应用来说,入门套餐(免费,写作本书时限制每天最多只能发送 400 封邮件)就够了。我们可以使用下面的命令添加这个扩展:

$ heroku addons:create sendgrid:starter

为了让应用使用 SendGrid 发送邮件,我们要配置生产环境的 SMTP 设置,而且还要定义一个 host 变量,设置生产环境中网站的地址,如代码清单 10.56 所示。

代码清单 10.56:配置应用在生产环境中使用 SendGrid

config/environments/production.rb

Rails.application.configure do
  .
  .
  .
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  host = '<your heroku app>.herokuapp.com'
  config.action_mailer.default_url_options = { host: host }
  ActionMailer::Base.smtp_settings = {
    :address        => 'smtp.sendgrid.net',
    :port           => '587',
    :authentication => :plain,
    :user_name      => ENV['SENDGRID_USERNAME'],
    :password       => ENV['SENDGRID_PASSWORD'],
    :domain         => 'heroku.com',
    :enable_starttls_auto => true
  }
  .
  .
  .
end

代码清单 10.56 中设置了 SendGrid 账户的用户名(user_name)和密码(password),但是注意,这两个值是从 ENV 环境变量中获取的,而没有直接写入代码。这是生产环境应用的最佳实践,为了安全,绝不能在源码中写入敏感信息,例如原始密码。这两个值由 SendGrid 扩展自动设置,11.4.4 节会介绍如何自己定义。如果好奇,可以使用下面的命令查看这两个环境变量的值:

$ heroku config:get SENDGRID_USERNAME
$ heroku config:get SENDGRID_PASSWORD

现在,应该把主题分支合并到主分支中:

$ bundle exec rake test
$ git add -A
$ git commit -m "Add password resets & email configuration"
$ git checkout master
$ git merge account-activation-password-reset

然后,推送到远程仓库,再部署到 Heroku:

$ bundle exec rake test
$ git push
$ git push heroku master
$ heroku run rake db:migrate

配置好 SendGrid 服务后,在生产环境的演示应用中使用你的电子邮件注册试试。你应该会收到一封激活邮件,如图 10.20 所示。如果忘记密码(或者假装忘了),可以使用 10.2 节实现的功能重设密码,收到的重设邮件如图 10.21 所示。

activation email production图 10.20:生产环境中的应用发送的账户激活邮件reset email production图 10.21:生产环境中的应用发送的密码重设邮件