使用 Rust 的 lettre 库发送邮件 - sbw Blog

使用 Rust 的 lettre 库发送邮件

来源: 石博文博客 | 浏览: 2578 | 评论: 8 发表时间: 2019-03-31

最近把自己的博客网站使用 Rust 语言重写了,利用的是 actix-web 这个框架。然后就一直想实现文章评论的回复邮件提醒这个功能,由于是自己写的网站,而且 actix-web 也没有提供像 wordpress 那样丰富强大的插件系统,所以这个需求就只能自己实现了。查了一圈之后,发现 lettre 这个库的 API、doc 什么的都比较完善,甚至直接提供了一个发邮件的 example,于是就准备利用这个库来实现一个发邮件的功能。



环境

截至现在写文章时,lettre的最新版本为0.9.0,所以文章中的代码都是在这个版本下编译测试通过的。我先是参考它的 Github 项目里 examples 目录中的smtp_google这个例子进行试验————很不幸,虽然能编译过,但是认证一直有问题,无法发送邮件。


一路坎坷

开源项目的示例代码更新缓慢早就不是新闻了,能编译过其实已经算是庆幸。为什么这么说呢,我大概查了一下这个库,发现他不久前才从0.8.0跳到了0.9.0,并且带来了一系列的 Break Changes。网上能找到的讨论及代码都是用旧 API 编写的,没有什么参考意义,但是这个认证失败让我感觉很诧异,既然能认证失败,那至少说明是与服务器成功建立了连接的。


后来我感觉可能是密码的问题,于是又专门去 Google 的应用专用密码那里弄了个 App Password 去登陆,发现还是登陆不上。不过这次偶然发现 Google 有一个新的认证方式叫XOAuth2(链接)。又去 lettre 项目中查找这个协议的相关 issue,果然,这个协议列在计划当中,还没有完全实现(链接)。


同时在Google的一个页面上也找到了一个可能的解决方案:可以在 Google 账户中设定允许较低安全等级的认证来兼容旧应用。那我估计就是因为这个问题了,因为这个新的XOAUTH2协议似乎就是去年才新出来的,不过我并不准备去调整账户的安全策略,于是又摸索了几下lettre的 API,然后利用Outlook的服务器发送邮件成功。


成功实现

核心代码如下,主要注意的是server addr要带上端口,否则会使用465端口,这个需要去邮件服务提供商那里查询,但是很多如Outlook并不使用465了。再一个就是要注意认证方式,一般都是STARTLS,如果要改的话,也是更改ClientSecurity这个选项。

虽然lettre提供了一个new_simple的函数直接为你设置了像TlsConnectorClientSecurity这样的参数,但是由于它都取的默认值,在很多情况下并不适用,还是分开设定每个参数比较好。有时候,封装过度也挺坑的~~~


除了上面的GMail XOAUTH2认证问题之外,还发现在连接QQ Mail服务器的时候存在UTF-8解码出错,因为lettre直接把收到的字符串给String::from_utf8了,这也是一个小 bug 吧。不过总体来说,一旦调试完成,发起邮件来还是很好用的。




  • 声明: 评论属于其发表者所有,不代表本站的观点和立场.
  • 任飘零 回复该留言 时间: 2019-07-21

    谢谢博主的代码! 在参考博主的代码后,我改写了一个Zoho邮箱的,分享有需要的朋友可以看看这个gist: https://gist.github.com/frankyxhl/cf0f731f5cabfdec1aeb56357eefc4f9 评论里贴不了代码……

  • sbw 回复该留言 时间: 2019-07-31

    赞!

  • 路人甲 回复该留言 时间: 2019-08-03

    请问UTF-8的那个问题怎么解决呀。。rust不太会写。。报了错就有点懵

  • sbw 回复该留言 时间: 2019-08-06

    你可以 RUST_BACKTRACE=1 运行一下,看看崩溃在哪里,应该是 rust-mail 这个库在 decode utf-8 的时候没有做字符有效性验证。

已有 4 位网友发表了一针见血的评论,你还等什么?
  • 昵称: *
  • 邮箱:
  • 网址:
  • 记住我的信息
  • Color
  • Red
  • Blue
  • Code
  • bash
  • cpp
  • css
  • java
  • js
  • perl
  • php
  • python
  • ruby
  • sql
  • xml