从发送的电子邮件到用户设置“取消订阅”链接的正确方法?

时间:2018-03-04 03:44:16

标签: php

我一直在使用一种方法来取消网站时事通讯中的人,并且当用户回复带有“取消订阅”字样的电子邮件时,该方法有效。

但是我想改变它,所以人们只需点击他们收到的电子邮件中的链接,重定向到我的网站,并成功取消该用户的使用权。但这种方式让我害怕人们可以玩网址,写不同的电子邮件和取消随机的人。

我知道这听起来很疯狂,但我对安全的东西有点偏执。

我没有代码,因为我不知道如何以正确的方式实现这一点,这意味着不使用url参数。

谢谢!

2 个答案:

答案 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
}

https://3v4l.org/tcqk8

答案 1 :(得分:0)

我刚看到以下内容: 电子邮件中的链接指向unsubscribe.php 用户再次在他的电子邮件中键入,在他的电子邮箱中确认。 我知道,www.mywebtodo.net的简报应用程序可能会更好一些。