我已经阅读了很多关于这个主题的SO帖子,但是他们似乎对此不屑一顾,所以也许如果我给你的真实世界的例子会影响答案。 < / p>
管理联系人列表并发送电子邮件的系统,但允许收件人使用唯一网址取消订阅。
由于这是一个公共页面,因此有人只需增加ID并取消订阅其他用户也是微不足道的。
我不想为每个用户/联系人/列表组合添加一个我必须存储在数据库中的唯一哈希。
最好的方法是什么?以下其中一项是否可以接受?
a)加密所有ID并解密服务器
b)根据3个ID和一个salt在url中包含一个哈希值,然后在服务器端确认
答案 0 :(得分:2)
我的观点是花了几年时间编写通讯软件(SAAS)的人。
为每个用户创建一个哈希\ joiner \ member sans将其与其他详细信息一起存储。在链接中使用它来取消订阅。
我的链接中总是有两个哈希,一个是发送哈希的简报,然后你可以跟踪他们取消订阅的那个,以及每个人的哈希值。
如果您确实希望在Thilo建议的一段时间后使unsub链接失效,您可以使用发送时事通讯发送日期来发送新闻稿的日期,但是您需要给他们一个替代方法,如果链接被认为是旧的。比如另一封电子邮件
强制性的一段代码。
$hash = md5(uniqid(true));
使用唯一索引存储在db字段中。如果您愿意,可以在混合中添加电子邮件地址,但uniqid()的设计是独一无二的。
答案 1 :(得分:2)
据我了解您的问题和意见,您的要求是
您将在http GET请求触发的服务器上执行操作,例如
http://youremailsystem.tl/unsubscribe&user=12&contact=34&list=56
虽然你的建议1),加密,增加了隐私的额外好处(URL没有给出执行哪些参数的行动),但数字2是更简单的方法。
你should use a MAC function to sign your URL parameters。输入将是您要签名的参数以及永不离开服务器的密钥。
$signature = hash_hmac('sha256', $url, $mysecretkey);
$url = $url . '&signature=' . $signature;
这使您的电子邮件中的取消订阅网址成为签名的一部分。
http://youremailsystem.tl/unsubscribe&user=12&contact=34&list=56&signature=b1812e463a7
每当GET请求进入时,您都可以验证参数是否未更改。
粗略代码:
// extract sent signature from url:
$sent_signature = //substr($sent_url ...
// strip signature from URL:
$sent_url = //substr($sent_url ...
// repeat hashing:
$correct_signature = $signature = hash_hmac('sha256', $sent_url, $mysecretkey);
if( $sent_signature == $correct_signature ) {
// do the unsubscribe
}
请注意,可以重复调用任何网址,因此请确保您永远不会重复使用您的任何ID,否则您可以让前用户取消订阅较新的用户,以便以后拥有他们的ID。
答案 2 :(得分:1)
为什么不愿意为每个用户创建一个唯一的令牌? 您不必为您描述的每个组合(用户/联系人/列表)创建它,而只需为您与电子邮件地址关联的用户创建它。
然后对每个动作使用该单个标记。并在使用后更改它。刚生成20个随机数的东西。它既简单又安全。
答案 3 :(得分:0)
我每次使用的所有邮件列表都会向我发送一封确认邮件,以取消订阅,其中包含一个可能随机且唯一的令牌,该令牌会在几个小时后过期。
我不想为每个用户/联系人/列表组合添加一个我必须存储在数据库中的唯一哈希。
您不必提前创建它们或无限期地存储它们。您可以在收到取消订阅请求时创建随机令牌,并在完成或过期时将其删除。
答案 4 :(得分:0)
在每个用户的哈希中使用电子邮件地址和用户ID(列表中可能存在的重复地址)。将哈希与地址一起存储在数据库中。
这样,如果您不知道其他用户的电子邮件,则很难重现哈希值。