【问题标题】:How to add one-click unsubscribe functionality to email newletters?如何为电子邮件通讯添加一键退订功能?
【发布时间】:2010-11-17 11:24:34
【问题描述】:

我想在我们的电子邮件通讯中自定义“取消订阅”链接,以便他们只需单击一下即可删除收件人。现在,他们只需指向一个通用页面,用户必须在该页面输入他们的电子邮件地址并选择他们想要取消订阅的时事通讯。

看起来这应该很简单,即只需将电子邮件地址和时事通讯 ID 作为 url 参数包含在内。但是当我查看我订阅的列表中的示例时,许多示例不包含可识别的地址,并且大多数似乎在参数中使用看起来像 guid 和/或散列值的东西。由此,我猜我应该对一些信息进行散列或以其他方式编码,以防止恶意滥用退订表单。

所以我的问题实际上是关于最佳实践,而不是重新发明轮子。是否有处理此类功能的标准方法?更具体地说,是否有理由不将收件人的电子邮件地址作为 url 的一部分?这似乎很简单,感觉就像我忽略了一些东西。

【问题讨论】:

  • 因为真的没有真正的答案,我只是评论一下:除非你有一个查找表来查找用户 ID 的散列,否则它不可能是真正的散列。我所做的是加密用户 id,这样当我取回它时,我可以解密它并取消订阅用户。
  • 在 URL 中包含电子邮件可能会起作用,除非您不希望人们取消订阅其他人的电子邮件地址,加密电子邮件将起作用,JWT 也将起作用,因为您无法修改内容。

标签: email usability


【解决方案1】:

您可以像这样对 URL 进行编码:

http://yourserver.com/unsubscribe/<encoded-email>/<expiration>/<signature>

&lt;signature&gt; 类似于 HMAC(secretkey, "&lt;encoded-email&gt;/&lt;expiration&gt;")。编码电子邮件可以只是电子邮件的 URL 编码,也可以是电子邮件的实际加密(AES+CBC+Base64 或类似)版本。不过,使用完全加密似乎没什么用 - 因为接收此邮件的人无论如何都有自己的电子邮件地址。

这种签名方案的优点是不需要任何数据库存储,同时保持安全,防止恶意尝试取消订阅。

或者(或除上述之外),您可以发送一封确认邮件以确认用户的意图。这样可以避免用户转发电子邮件时出现问题。

【讨论】:

  • 所以如果我理解的话,你基本上是说在取消订阅链接中包含电子邮件地址和电子邮件地址+密钥的哈希值;然后我的取消订阅网页将重新散列电子邮件地址+密钥并确保它与传递给页面的散列值匹配。这可以防止滥用,因为密钥值仅存在于我们的服务器上。到目前为止,这是有道理的,但是 的目的是什么?
  • @Matt,过期是为了确保这些网址不需要永远保密。 :)
  • @SanKrish 好吧,语言部分可以很容易地从 C# 转换为 Java,但 Java 中的 HMAC 库可能会有很大不同。
  • @Armstrongest 感谢您的回复。您能否详细说明使用 expire 。我怎样才能实现它?
  • @Armstrongest 如何创建过期令牌。任何参考资料都会非常有用
【解决方案2】:

如果您的邮件列表软件使用老式的最佳做法,则应该有一个“取消订阅”电子邮件地址 - 从您要取消订阅的地址(可能带有固定的主题行)通过电子邮件发送到该地址通常可以解决问题(以及发送确认电子邮件)。在这种情况下,添加格式正确的“mailto”链接应该可以解决问题。

【讨论】:

  • 我喜欢这种方法,但我正在处理现有的代码库和架构,这使得走基于 Web 的路线变得更容易。
【解决方案3】:

在 URL 中的查询中没有纯文本电子邮件地址的两个原因是您不希望恶意用户从您的邮件列表中取消订阅您的客户。

第二个可能只会影响发送数百万封电子邮件的公司,是让垃圾邮件发送者更难“嗅探”真正的电子邮件地址。

【讨论】:

    【解决方案4】:

    在简报中嵌入电子邮件地址是不安全的。不确定你的,但许多时事通讯最终都在网络上的一些存档中。有专门设计用于从邮件列表档案中收集地址的垃圾邮件机器人。

    电子邮件是一种更安全的技术。设置一个邮件帐户以取消订阅并从邮件标题中获取电子邮件地址。如果您使用任何邮件列表软件,它应该已经处理了这个问题。

    【讨论】:

      【解决方案5】:

      我在 Web 应用程序中使用了某种简单的方法,但我不确定它对于其他 Web 应用程序的用途是否足够高效和安全。

      在我的应用程序中,当用户单击取消订阅链接时,我会将它们转发到我的服务器上的一个页面,其中包含一个查询字符串,该字符串是用户电子邮件地址和它在我的 DB 中的唯一 ID 的组合(两者都最好加密) .

      然后在我的页面的页面加载功能中,首先我decryptEmail address,然后我检查电子邮件地址是否存在于我的数据库中,然后如果答案为真,我检查@ 987654324@ 和Email address 是相关的,最后我根据其他标准删除了用户。

      我认为它可以在不向DB 输入任何额外数据的情况下完成这项工作。

      现在我正在寻找一种方法来确定单击链接的人是否是我向其发送电子邮件或电子邮件已转发给他/她的第一手人。这样除了真正的用户之外,没有人可以(至少很容易地)取消订阅他/她!

      [在完成退订过程之前询问安全问题是我迄今为止考虑的一件事]

      【讨论】:

        【解决方案6】:

        我为每个电子邮件地址分配一个唯一的 32 个字符的标识符字符串(使用 MySQL:MD5(UUID())),并且只在取消订阅链接中提交该标识符。

        【讨论】:

          【解决方案7】:

          我给我发送的每封电子邮件一个 ID,然后在他们单击退订时查找电子邮件 ID。

          http://www.foo.com/unsubscribe.asp?ID=1234

          然后取消订阅我发送 1234 的电子邮件地址。

          【讨论】:

          • 任何阅读此内容的人,请勿遵循此建议。他的建议不仅不能很好地适用于任何邮件系统,而且也不安全。他有一个易于识别的模式,无需验证持有电子邮件的用户的真实性。如果您不想要开销和简单但足够安全的系统实施,请查看接受的答案。
          • 有人可以使用 curl 编写脚本并取消订阅所有用户。小心这种方法。为每个用户使用一个唯一的令牌,或者让他们用其他一些验证来填写他们的电子邮件。
          猜你喜欢
          • 2016-09-30
          • 1970-01-01
          • 1970-01-01
          • 2016-11-19
          • 2015-08-30
          • 1970-01-01
          • 2012-06-23
          • 1970-01-01
          • 2011-03-05
          相关资源
          最近更新 更多