Search code examples
email-spec

How to pass long URL in plain text emails?


I have this account creation email that is sent out to anyone who is trying to create an account as I need to authenticate that they are who they say they are.

However, my issue here is that the URL where they need to click when they receive my email is too long and some email clients do not handle that very well and sometimes truncates the URL thus making the URL invalid when clicked.

Because the URL contains the domain name, the hashed email and a long activation code. It looks something like this.

http://domain.com/activation?email=75a5867d3df134bededbaf24ff17624d&key=8fecb20817b3847419bb3de39a609afe

While some email clients are ok with this but some are not...And I don't want to use HTML email and rather stick with plain/text email. Also I heard horrible stories using URL shorteners so I am not sure if I should use them...

Any insights in this area is appreciated!


Solution

  • I would definitely agree with Jason: shorten your url.

    Think of what you really need.

    • Most likely the email address is in the database already, so you can refer to if with a short ID (let's say 7 numbers max). Your signature can be something very simple as substring (base64_url(md5(email+salt)), 0, 5). 5 base64 characters are 64^5=about 1 billion possibilities. This is probably secure enough (and what would the real damage be if someone registered with a wrong email address). So your url would be http://domain.com/activation?email=1234&key=aD5Y_, http://domain.com/activation?e=1234&k=aD5Y_ or even http://domain.com/activation?e=1234aD5Y_ . In the last format you know the last 5 characters are the key, so the rest is the id. Note that the code example assumes md5 to return in an 8-bit string format (and not hex string format), and base64_url uses a url safe base64 method. Also, some background info on a salt.
    • If your email address has a long id or needs to be encoded in the url as well, or the above is not short enough yet, consider an even shorter form. Basically this will result in making your own url shortener. Just before you insert the link into the email, generate some random 5 character string. Insert this string as key into memcached (or the database), with as value the original url. Then your url could be http://domain.com/redirect?key=rT-tW . When you see this in your app, just retrieve the original url from the database/memcached and redirect there.

    Do make sure that your system is robust against the following:

    • Someone enters an email address (their real email), you send the link
    • That person changes their email address into something fake on the website before clicking the link, you send a new email to the new (fake) email address
    • They now click the link from the first email and your website confirms their email address in the second (fake) form.

    One way to do this is make sure to use the email address itself (and not for instance just the user id) in the key generation, as suggested above.