我一直在使用一种方法来取消网站时事通讯中的人,并且当用户回复带有“取消订阅”字样的电子邮件时,该方法有效。
但是我想改变它,所以人们只需点击他们收到的电子邮件中的链接,重定向到我的网站,并成功取消该用户的使用权。但这种方式让我害怕人们可以玩网址,写不同的电子邮件和取消随机的人。
我知道这听起来很疯狂,但我对安全的东西有点偏执。
我没有代码,因为我不知道如何以正确的方式实现这一点,这意味着不使用url参数。
谢谢!
答案 0 :(得分:1)
使用hash_hmac()。
对电子邮件进行签名$token = hash_hmac('sha256', 'email@example.com', 'secret-server-key');
然后将其传递给电子邮件模板,因此您的取消订阅链接将是:
<a href="http://example.com/unsubscribe?email=email@example.com&token=abcec5cdca4d760d34e8c02107ae68f251f08aaa9dd14956c2f0ab84a33f6441">
然后,当用户点击它时,请签署电子邮件参数,如果令牌匹配则继续。
<?php
if (isset($_GET['email'], $_GET['token']) &&
$_GET['token'] === hash_hmac('sha256', $_GET['email'], 'secret-server-key')
) {
// lagit
}
只要您永远不会共享secret-server-key
。
编辑:
接受@FunkFortyNiner的评论
您可以将电子邮件签名并编码为单个令牌。基本上就像JWT现在但没有json; p
所以你的令牌看起来像是:ZW1haWxAZXhhbXBsZS5jb20.abcec5cdca4d760d34e8c02107ae68f251f08aaa9dd14956c2f0ab84a33f6441
但是在检查时会涉及更多代码。如果你的真正的paronoid也许值得它。
<?php
$email = 'email@example.com';
function base64url_encode($str) {
return rtrim(strtr(base64_encode($str), '+/', '-_'), '=');
}
function base64url_decode($str) {
return base64_decode(strtr($str, '-_', '+/'));
}
$token = base64url_encode($email).'.'.hash_hmac('sha256', $email, 'secret-server-key');
// mock got token
$_GET['token'] = $token;
// when checking
if (isset($_GET['token'])) {
$tok = explode('.', $_GET['token']);
// check token parts
if (count($tok) !== 2) {
// not valid token
throw new \Exception('Invalid token!');
}
// check email segment
if (!isset($tok[0]) || !filter_var(base64url_decode($tok[0]), FILTER_VALIDATE_EMAIL)) {
// not valid email
throw new \Exception('Invalid token!');
}
$email = base64url_decode($tok[0]);
if ($tok[1] !== hash_hmac('sha256', $email, 'secret-server-key')) {
// failed verification
throw new \Exception('Invalid token!');
}
//
echo 'Its lagit!';
// do somthing with $email
}
答案 1 :(得分:0)
我刚看到以下内容: 电子邮件中的链接指向unsubscribe.php 用户再次在他的电子邮件中键入,在他的电子邮箱中确认。 我知道,www.mywebtodo.net的简报应用程序可能会更好一些。