I want to provide a link for users to unsubscribe to our newsletter.
I don't want the actual email address to show up in the url. So I
would like it something like /unsubscribe/wx313asdf31. What is the
simplest method of encrypting the email to a URL compliant string?
It might be possible to use another key from that table (perhaps you have an ID column) and use that to unsubscribe users. Is anything like that possible?
I want to provide a link for users to unsubscribe to our newsletter.
I don't want the actual email address to show up in the url.
Why not? If you're only sending the link to that user, there's no
security risk.
So I
would like it something like /unsubscribe/wx313asdf31. What is the
simplest method of encrypting the email to a URL compliant string?
As James suggested, if you've already got the users stored in the DB,
then just use their DB ID or a random unique string that you store in
the DB. If you're not storing e-mail addresses in the DB, then you need
some sort of reversible encryption. Base64 or uuencode would also work
if you don't need high security.
1. I can't use the actual email address because AOL will redact the
address
if a complaint is filed.
Um, what? Not sure I understand.
2. I can't use the actual ID, because someone could have a field day
unsubscribing people
3. I could store a random string in the db, but that seems like
overkill
It's actually very easy to do. Heck, you could even use it as the
primary key.
Is there a simple way to obfuscate the email address?
I already suggested a couple. If all you need is to make it not look
like an e-mail address, though, why don't you just replace the @ with a
/ or something?
Instead of encrypting/decrypting some data, one typical approach to do
this type of thing is to employ (cryptographic) hashing to verify that
some requested action is valid, as well as to try and discourage
malicious request attempts.
# user doesn't exist in db?
if user_id < 1 or User.count(:conditions=>["id=?", user_id]) < 1
# log it and redirect to ....
end
# email unsubscribe link to user?
if dt < 1 or hd.blank?
dt = Time.now.to_i
hd = unsubscribe_hd(user_id, dt)
unsubscribe_url = "#{UNSUBSCRIBE_URL_PRE}/#{user_id}/#{dt}/#{hd}"
# email url to user and redirect to ....
end
# invalid hd?
expected_hd = unsubscribe_hd(user_id, dt)
if hd != expected_hd
# log it and redirect to ....
end
# unsubscribe the user and redirect to ...
end
...
protected
def unsubscribe_hd(user_id, dt)
secret_hd = Digest::SHA256.hexdigest(UNSUBSCRIBE_SECRET)
return Digest::SHA256.hexdigest("#{user_id}#{dt}#{secret_hd}")
end
...
I like the idea of using a real piece of data (the id) and then a hash to validate that its not some random get request! That is a nice, slick, way to avoid complicated encryption or junking up the database. Thanks!