尝试发送电子邮件时收到“必须首先发出 STARTTLS 命令”
-
08-07-2019 - |
题
我在尝试使用时遇到错误 action_mailer_tls
在我的 Rails 应用程序中与 Gmail 通信的插件:
Must issue a STARTTLS command first
其他人好像也遇到过 同样的问题:
问题是Gmail需要TLS 身份验证,但标准的 Ruby net/smtp 库不支持 TLS。
该文章建议遵循以下步骤,我也这样做了:
当然有一个有用的插件 由Marc Chung创建以克服这个问题 障碍。你可以在这里找到它,然后 手动将其添加到您的项目或您 可以将其导出到您的插件 目录。
$ cd vendor/plugins
$ svn export http://code.openrain.com/rails/action_mailer_tls/
无论哪种方式,请确保您需要 “smtp_tls”
现在,您只需要更新您的 smtp_settings,如果你还没有这样做 已经。
- ActionMailer::Base.smtp_settings = {
- :地址=>“smtp.gmail.com”,
- :端口=> 587,
- :domain => "domain.com",
- :user_name => "user@domain.com",
- :密码=>“密码”,
- : 身份验证 => : 普通
- }
如果有任何关于与 Gmail 对话的更好解决方案的建议,我们将不胜感激。
解决方案
我使用 Alexander Pomozov 的解决方案从我的 Rails 应用程序与 Gmail 进行通信。我相信原来的文章已经消失了,但有人复制了谷歌缓存 在这里.
lib/smtp_tls.rb
require "openssl"
require "net/smtp"
Net::SMTP.class_eval do
private
def do_start(helodomain, user, secret, authtype)
raise IOError, 'SMTP session already started' if @started
check_auth_args user, secret, authtype if user or secret
sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
@socket = Net::InternetMessageIO.new(sock)
@socket.read_timeout = 60 #@read_timeout
#@socket.debug_output = STDERR #@debug_output
check_response(critical { recv_response() })
do_helo(helodomain)
if starttls
raise 'openssl library not installed' unless defined?(OpenSSL)
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect
@socket = Net::InternetMessageIO.new(ssl)
@socket.read_timeout = 60 #@read_timeout
#@socket.debug_output = STDERR #@debug_output
do_helo(helodomain)
end
authenticate user, secret, authtype if user
@started = true
ensure
unless @started
# authentication failed, cancel connection.
@socket.close if not @started and @socket and not @socket.closed?
@socket = nil
end
end
def do_helo(helodomain)
begin
if @esmtp
ehlo helodomain
else
helo helodomain
end
rescue Net::ProtocolError
if @esmtp
@esmtp = false
@error_occured = false
retry
end
raise
end
end
def starttls
getok('STARTTLS') rescue return false
return true
end
def quit
begin
getok('QUIT')
rescue EOFError, OpenSSL::SSL::SSLError
end
end
end
配置/环境.rb
(在其他内容之后添加)
require “smtp_tls”
ActionMailer::Base.smtp_settings = {
:address => “smtp.gmail.com”,
:port => 587,
:authentication => :plain,
:user_name => “someone@openrain.com”,
:password => ’someonesPassword’
}
正常使用 ActionMailer。
其他提示
使用 Ruby 1.8.7 和 Rails 2.3.4(尽管它已经存在了多个版本),我通过使用以下方法取得了成功,无需特定于 TLS 的 ActionMailer 插件 :enable_starttls_auto
选项。示例配置(来自生产环境)如下所示:
ActionMailer::Base.smtp_settings = {
:enable_starttls_auto => true,
:address => "smtp.gmail.com",
:port => 587,
:domain => "domain.com",
:authentication => :plain,
:user_name => "username@domain",
:password => "secret"
}
我启用了 starttls 使用 :enable_starttls_auto => true
但仍然遇到同样的错误。最后,我无需对代码进行任何更改即可解决该问题。如果您使用 smtp.gmail.com 发送邮件,则必须首先允许安全性较低的应用程序使用您的电子邮件发送邮件。为此,请使用您要发送邮件的帐户登录并转到这个链接 和 打开 访问不太安全的应用程序。
编辑:如果不允许您将设置更改为安全性较低的应用程序,则您应该联系该域的管理员帐户持有者以更改设置以允许用户使用安全性较低的应用程序。
如果您拥有管理员权限,您可以允许用户更改其不太安全的应用程序设置,您可以从 https://admin.google.com/domainname.com/AdminHome#ServiceSettings/notab=1&service=securitysetting&subtab=lesssecureappsaccess
附:不要忘记更改上面链接中的域名。
希望这能有所帮助!
我正在运行 Rails 2.3.4,尽管我认为(通过谷歌搜索)你不需要任何插件,只需要该行
:enable_starttls_auto => true,
实际上,当我使用上面ski发布的Alexander Pomozov解决方案时,我才让它工作(非常感谢你们)。有什么评论可以解释为什么吗?会很棒,但我很高兴它有效。