Encode and Encrypt Email Addresses

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?

Thanks, Tom

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?

TomRossi7 wrote:

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.

Thanks, Tom

Best,

  1. I can’t use the actual email address because AOL will redact the address if a complaint is filed.
  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

Is there a simple way to obfuscate the email address?

Thanks! Tom

Tom Rossi wrote:

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?

Thanks! Tom

Best,

Hey Tom,

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.

You could try something like:

### in routes: ... map.connect '/ unsubscribe/:user_id/:dt/:hd', :controller=>'test', :action=>'unsubscribe' map.connect '/ unsubscribe/:user_id', :controller=>'test', :action=>'unsubscribe' ...

### in controller: require 'digest/sha2' ...

UNSUBSCRIBE_SECRET = "somelongrandomstring" UNSUBSCRIBE_URL_PRE = "Foo.com; ...

def unsubscribe   user_id = params[:user_id].to_i   dt = params[:dt].to_i   hd = params[:hd]

  # 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 ...

Jeff

1 Like

Jeff,

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!

–Tom