I am thinking that I create a deactivation code put that in the unsubscribe link along with their user id. Then when a recipient of my newsletter clicks the link, I can look up their user id and see if the deactivation code matches.
Does this sound like the best way?
What are some other ways?
From an end-user perspective, single-click unsubscribe is excellent.
However, using hash(id + secret) is insecure because a clever attacker can very quickly "brute force" the secret, then proceed to unsubscribe every user in your DB simply by incrementing the ID.
It is much more secure to keep the ID "semi-secret" on the server and use the e-mail address to lookup the user upon unsubscribe. This way, a successful unsubscribe requires pairing an email address with the correct ID. You can make this even more secure by saving a truly secret key for each user and using that instead of the ID. This is especially necessary if the email + ID pairs are published.
So, for example, your unsubscribe link would look like this:
http://mydomain.com/unsubscribe?email={$email}&hash={$hash}
And a server-side function to generate $hash would look like this in PHP:
<?php
function unsubscribeHash($id, $email) {
$hashSecret = 'Fz!Fx~36N66>io3B-vlPDshdRxos8JjCd4+Ld-s2^ca{19Q/5u';
return sha1($id . $email . $hashSecret);
}
?>
Then, to complete the unsubscribe, you will lookup the user by email, and verify
$_GET['hash'] == unsubscribeHash($user_id, $_GET['email'])
You could just use an hashing algorithm to secure the userID (so that nobody can unregister all your DB with a nasty loop).
You'll end up with two params : userID and hash.
The advantage is that you won't need to store any mapping between deactivation code and userID.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With