如何生成电子邮件退订链接

14

我有一个简单的Rails应用程序,用户可以向10个以上的人发送群发邮件。在这封邮件中,我想在底部始终放置一个链接,以便最终用户可以单击它来取消通知。我不太清楚该如何解决这个问题。

可以在电子邮件中只放置一个通用链接,用户点击后输入其电子邮件地址以取消订阅。但是这样做的问题是,其他用户可能会取消其他人的订阅。

我想为每封电子邮件生成一个特定的唯一链接,以便当用户单击它时,它会自动将该用户从列表中删除,而无需进行任何额外的工作。

我应该从哪里开始才能实现这个功能?


嗨@Patrick,你能和我分享你的最终解决方案吗?因为我也在寻找同样的东西,谢谢。 - iCyborg
2
你可以尝试这个教程,非常有帮助:http://ngauthier.com/2013/01/rails-unsubscribe-with-active-support-message-verifier.html - duykhoa
2个回答

17

您的取消订阅链接可能如下所示:http://host/application/unsubscribe?address=example@example.com&token=598bbdf39bc8f27b07fe85b6a7dd8decef641605

使用电子邮件地址和一个幻数生成令牌。理想情况下,应使用HMAC与SHA256,但即使只是sha1也应该足够好:

$ echo "secret token example@example.com" | sha1sum
598bbdf39bc8f27b07fe85b6a7dd8decef641605  -

“secret token”部分应该在您的应用程序中固定,而“example@example.com”需要与电子邮件地址匹配。

当然,如果秘密令牌泄露,您将回到任何人都可以退订所有人的情况。您还可以在数据库中存储每个用户的魔术令牌,以验证URL中的令牌,这不会比此方法更难,而且绝对更安全。


我喜欢这个想法,但有几个问题。我如何在Rails内部生成该令牌?并且该令牌将与每个收到电子邮件的人相关联(数据库中的新列)。因此,当用户单击取消订阅时,我的Rails代码会读取该令牌...在表格上进行查找,并在找到具有该令牌的人时取消订阅。 - Patrick
@Patrick,Jesse的回答包括SecureRandom,听起来是一个很好的魔法令牌来源。你可以将令牌存储在用户模型中,或者创建一个只包含用户ID和取消订阅令牌的新表,并在发送电子邮件时填充它。 - sarnold
2
这种方法与仅使用包含加密电子邮件地址(非哈希)和一个或两个秘密令牌相比如何?然后解密它们以在应用程序中检查秘密令牌是否与电子邮件地址一致。我在考虑秘密令牌可以是已经存在的东西,例如用户的ID或添加日期。 - Michael K

3
如果你有一个名为EmailTemplate的模型和一个名为Subscriber的模型,那么你的代码可能如下所示:
@email_template = EmailTemplate.find(3)
@email_template.subscribers.each do |subscriber|
  Notifier.deliver_template(:email_template=>@email_template, :subscriber=>subscriber)
end

所以,你可以改为
email_delivery = EmailDelivery.create(:email_template=>@email_template, :subscriber=>subscriber)
Notifier.deliver_template(email_delivery)

然后,email_delivery的before_create会生成一个令牌。每个email_delivery都应该使用随机密码生成器。SecureRandom在生成随机令牌方面表现良好:SecureRandom p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"

将email_delivery令牌包含在您的电子邮件中,然后仅基于该令牌进行查找。


我还没有创建控制器/模型,但我也会尝试您的方法。 - Patrick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接