8

This is a more focused question triggered by an earlier posting here. I need to authenticate a user's email address by proving he/she has access to it. I've copied below a generic email authentication you'd expect to see when joining a developer forum or user group. As part of the registration process, you'd provide your email address, and then you'd get an email asking you to click on something to verify your email address.

I need to code whatever happens when a user clicks on the link in the email. So my question is -- how do I do that?

What technologies are involved? Can anyone walk me through the steps? I prefer Java or Linux scripting language like bash. Better yet, is there any software developed for this purpose I can install on my Linux server and somehow integrate it to talk with my database? How is this done in practice? I don't want to reinvent something if it's already available.

To confirm your email address of: 

youremail@yourdomain.net 

please send a short reply to this address: 

users-sc.1496854427.ckdpbmhncdlkjadkajfpecc-mylist=yourdomain.net@listdomain.com 

Usually, this happens when you just hit the "reply" button. 
If this does not work, simply copy the address and paste it into 
the "To:" field of a new message. 

or click here: 
mailto:users-sc.1496854427.ckdpbmhncdlkjadkajfpecc-mylist=yourdomain.net@listdomain.com  

This confirmation serves two purposes. First, it verifies that I am able 
to get mail through to you. Second, it protects you in case someone 
forges a subscription request in your name. 

Some mail programs are broken and cannot handle long addresses. If you 
cannot reply to this request, instead send a message to 
<users-request@listdomain.com> and put the 
entire address listed above into the "Subject:" line. 
Community
  • 1
  • 1
ggkmath
  • 4,188
  • 23
  • 72
  • 129
  • 1
    Most end users prefer clicking a verification link rather than sending a verification email reply. To check if they've clicked the link, generate a registration code specifically for them, and when they click an email verification php link with the code as the get parameter, iterate through your user table to find the one with that code, and change a flag in that mysql table to mark that user as having been email verified. – FThompson May 11 '12 at 04:40
  • Sure, but how to code between this step: `when they click a ... link` and this step: `iterate through your user table...`. That is, what exactly happens when the link is clicked? What should the link be? How does this work? What is on the receiving end that's listening to when the link is clicked? Examples, keywords, etc. – ggkmath May 11 '12 at 04:45
  • 1
    An example of a verification link could be `http://example.com/verify?c=b53kl23d0ko234r5kok32490kdjk2uise` where that ending mess of numbers is a generated verification code for that user. Your script which sends the verification email should also create this generation code and save it into a mysql table which could have fields for verification code, expiration date (of the code), and user id. Upon that link being followed, the script at verify/index.php should iterate through the table to find the user with that verification, and then set a flag in your user table to true for verified. – FThompson May 11 '12 at 04:51
  • Thanks, I can do everything except the last sentence. When the user clicks the link, this code is somehow obtained by the website, which it then communicates to, say, a Java or PHP method, which takes care of the rest? Can you describe this process a little more? – ggkmath May 11 '12 at 04:55
  • 1
    The $_GET variable in php allows you to acquire data input which is in the url itself, i.e. in the following url, http://site.com/script.php?param=value, calling $_GET['param'] within script.php would return "value". Once you have obtained the verification code in this style, you can utilize a mysql table to store information about what verification code corresponds with what user. – FThompson May 11 '12 at 05:05
  • How do you know if the user has not forwarded the email to some other email address. So, lets say if the user has registered with email A and clicks the link from email B, I want to fail the verification. How can I do that? – Farhad Sep 22 '16 at 12:35

3 Answers3

7

In your user database you need to have a staging users table (or in the main users table add a column indicating whether the user is active and default the indicator to "no"). When the user first registers, you generate a unique hash code from part of the user's info, e.g. Use md5 on user primary key and name (or some other set of user's variables which you can get back by decrypting) . Make this hash code a query string parameter in the link you send to the user. Finally, when the user clicks on the link, get the hashcode from the query string, decrypt it and match the decrypted values to the user row in your database. If a match is found, set the "active" indicator to true, and presto. Alternately, if you used a staging table, then move the user record to the "active users" table which you use to do your authorization on.

Nickoli Roussakov
  • 3,434
  • 16
  • 22
  • `when the user clicks on the link, get the hashcode from the query string` -- how to do this (exactly)? I'm sorry if it's obvious, but this is what I'm struggling with. – ggkmath May 11 '12 at 05:01
  • You need to have a page on the server dedicated to processing email links, e.g. http://mysite.com/user-activation.aspx (or php, or jsp, or whatever you're using). When a request comes into this page, i.e. when the user clicks on the link, simply do request.GetParameter("hashcode") [or whatever you set your query string parameter to be]. In ASP.NET you would use the function: age.Request.QueryString["youQueryStringField"]; In Java/JSP: String someName = request.getParameter("yourQueryStringField"); and in PHP the statement is: $_GET["yourQueryStringField"]) – Nickoli Roussakov May 11 '12 at 05:04
  • Thanks, your reply really helps! For Java, I think the answer lies in using Java servlets. The link I provide in the email simply calls a servlet. For example: http://www.servletworld.com/servlet-tutorials/simple-servlet-example.html – ggkmath May 11 '12 at 16:01
  • The answer selected here is also relevant: http://stackoverflow.com/questions/4533290/how-to-get-data-from-activation-link-with-java-servlet as well as: http://stackoverflow.com/questions/1907482/call-a-servlet-on-click-of-hyperlink – ggkmath May 11 '12 at 17:14
  • And: http://stackoverflow.com/questions/2267064/can-you-call-a-servlet-with-a-link – ggkmath May 11 '12 at 17:28
  • And: http://stackoverflow.com/questions/2395251/how-to-call-servlet-file-using-html – ggkmath May 11 '12 at 17:34
  • And: http://www.webpelican.com/internet-programming-2/links-get-method/#get-method along with example code: http://www.webpelican.com/internet-programming-2/links-get-method/source/LinksGetMethod.java – ggkmath May 11 '12 at 17:46
  • And: http://stackoverflow.com/questions/3756300/java-servlet-getparameter-for-a-param-that-is-a-url – ggkmath May 11 '12 at 17:52
  • And: http://www.javadb.com/get-request-parameters-in-a-servlet and also: http://www.javamex.com/tutorials/servlets/parameters.shtml – ggkmath May 11 '12 at 17:57
  • http://www.sonatype.com/books/mvnex-book/reference/web-sect-adding-simple-servlet.html – ggkmath May 16 '12 at 17:16
3

Replying to a unique email to verify someone's email has an inherent flaw, it can be faked (unless you check headers and ip). For example, I visit your site for registration. You tell me to reply at users-sc.1496854427.ckdpbmhncdlkjadkajfpecc-mylist=yourdomain.net@listdomain.com. I use a mail() function using spam bot to reply. Game Over. Purpose defeated.

Instead, you can send me a verification link on my register id. Something like example.com/verify?userid=1&hash=67gk65fs6714fgsHguj

In the users table:

id|username|status|onetimehash
--+--------+------+-------------------------
 1|testuser|    0 |67gk65fs6714fgsHguj

Now, in your verify call check userid and hash. If they match against values in your db, you can safely verify the user. For generating hash, you can take md5 or sha1 value of username mixed with some salt like timestamp or some random number.

UPDATE If you are going with the former solution, i.e, capturing user's reply to validate email, you will have to setup your own mail server. Fetchmail may help you. You will have to programmatically read the email headers and extract required info from the <to>,<from> or <subject> fields. Like userid=1496854427 and hash=ckdpbmhncdlkjadkajfpecc. You may need regex in this process. Once you have these values, its pretty straightforward, check them against database values.

Bottom-line is: Former method is not just more tedious, its also more vulnerable than the latter. Most webapps use the 2nd solution, as its cleaner and wiser.

jerrymouse
  • 16,964
  • 16
  • 76
  • 97
  • Thanks jerrymouse, silly question: how exactly does the user's reply to the email make it back to the middle-tier logic (e.g. Java)? This is my only question. – ggkmath May 11 '12 at 04:59
2

I knew one link which has the best answer given by BalusC
Here is link:better answer.
I have implemented that in my project. Hope this will help others.

Community
  • 1
  • 1
Aniket Kulkarni
  • 12,825
  • 9
  • 67
  • 90