Node Email Verification Script

In recent tutorial i have explained about sending e-mail using nodemailer package of Node.js. In this tutorial i am going to explain you about e-mail verification system using node.js script which is mandatory thing in sign-up form in order to avoid spam registration. You can integrate this code to any web application which is having user sign up module.

You can download it from Github.

Note : To run the script you have to change two lines in Server.js. You have put your Gmail ID and password in order to send e-mail to any mailbox. Change it once you see the demo.

We are going to use nodemailer to send email’s. To verify e-mail we will generate one random key in our script, store it, and when user click on verification link in e-mail we will fetch the key from that link and compare it to the store one.

rand=Math.floor((Math.random() * 100) + 54);

The above code will generate random number and our job is to store it in temporary variable for further comparison.

So let’s begin with creating package.json file.

package.json
{
  "name": "email-node",
  "version": "1.0.0",
  "dependencies": {
        "nodemailer": "latest",
    "express": "latest"
  }
}

Switch to the project folder (if you don’t have one, create one with any name and paste package.json in it) and type npm install to load all dependencies.

Server script is same as old post ( Send email using Node.js) with one simple difference. i have added one more router (app.get(/verify)) and in that i am verifying information (which is random ID) by clicking to the verification link. Here is a complete code.

Server.js
var express=require('express');
var nodemailer = require("nodemailer");
var app=express();
/*
    Here we are configuring our SMTP Server details.
    STMP is mail server which is responsible for sending and recieving email.
*/

var smtpTransport = nodemailer.createTransport({
    service: "Gmail",
    auth: {
        user: "Your Gmail ID",
        pass: "Gmail Password"
    }
});
var rand,mailOptions,host,link;
/*------------------SMTP Over-----------------------------*/

/*------------------Routing Started ------------------------*/

app.get('/',function(req,res){
    res.sendfile('index.html');
});
app.get('/send',function(req,res){
        rand=Math.floor((Math.random() * 100) + 54);
    host=req.get('host');
    link="http://"+req.get('host')+"/verify?id="+rand;
    mailOptions={
        to : req.query.to,
        subject : "Please confirm your Email account",
        html : "Hello,<br> Please Click on the link to verify your email.<br><a href="+link+">Click here to verify</a>"
    }
    console.log(mailOptions);
    smtpTransport.sendMail(mailOptions, function(error, response){
     if(error){
            console.log(error);
        res.end("error");
     }else{
            console.log("Message sent: " + response.message);
        res.end("sent");
         }
});
});

app.get('/verify',function(req,res){
console.log(req.protocol+":/"+req.get('host'));
if((req.protocol+"://"+req.get('host'))==("http://"+host))
{
    console.log("Domain is matched. Information is from Authentic email");
    if(req.query.id==rand)
    {
        console.log("email is verified");
        res.end("<h1>Email "+mailOptions.to+" is been Successfully verified");
    }
    else
    {
        console.log("email is not verified");
        res.end("<h1>Bad Request</h1>");
    }
}
else
{
    res.end("<h1>Request is from unknown source");
}
});

/*--------------------Routing Over----------------------------*/

app.listen(3000,function(){
    console.log("Express Started on Port 3000");
});

Let me explain you the code. In app.get(‘/verify’) router. First we are determining whether the URL from which ‘/verify’ is invoked is valid or not. Those validation include comparing Host name from where the email is been send, and the host name determine by this router as well as whether it is HTTP or not.

Once domain is authorize, we are comparing our store ID (rand) with ID fetched from URL (req.query.id). If they match then only we can say that account is verified and source of e-mail is valid.

We are using HTML and jQuery for front-end application and here is HTML code which have used as index.html.

index.html
<html>
<head>
<title>Node.JS Email application</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
    var from,to,subject,text;
    $("#send_email").click(function(){     
        to=$("#to").val();     
        $("#message").text("Sending E-mail...Please wait");
        $.get("http://localhost:3000/send",{to:to},function(data){
        if(data=="sent")
        {
            $("#message").empty().html("<p>Email is been sent at "+to+" . Please check inbox !</p>");
        }

});
    });
});
</script>
<style>
#container
{
    margin-left:400px;
    margin-top:50px;
}
#to,#subject,#content
{
    font-family: "Segoe UI";
    font-size:18px;
    width:530px;
}
h1
{
    font-family: "Segoe UI";
    font-size:40px;
    color: #3b5998;
}
p
{
    color:green;
}
#send_email
{
    font-size:15px;
    font-family: "Segoe UI";
}
#message
{
    font-size:18px;
}
</style>
</head>
<body>
<div id="container">
<h1>Email-verification System in Node.js</h1>
<input type="text" id="to" placeholder="Enter E-mail which you want to verify"><br>
<button id="send_email">Send Email</button><br>
<span id="message"></span>
</div>
</body>
</html>

When user click on Send button, we are calling Node Server using complete URL (http://localhost:3000/send) and in “/send” router we dealt with sending e-mail. I hope this is useful to you.

Shahid

Founder of Codeforgeek. Technologist. Published Author. Engineer. Content Creator. Teaching Everything I learn!

Related Posts

85 Comments

  1. I really like what you guys are usually up too.
    This type of clever work and exposure! Keep up the terrific works guys I’ve you guys to my blogroll.

  2. Hi, thx for the nice tutorial. I’m unable to figure out where the rand variable is stored for camping when user sends the verify request
    Thanks

    1. “rand” variable is holding the random/unique number generated by system to send to particular email as a link. When user clicks on that link and comes back to our program, we will again verify it with the random key we have generated. In this way we will be sure about verification of that particular email account.

  3. Hi and thank you for this guide, I have a problem though, I created a simple app that just sends a mail to one of my adresses and i get this error:
    [Error: Invalid login]
    code: ‘EAUTH’,
    response: ‘534-5.7.14 Please log in via your web browser and then try again.n534-5.7.14 Learn more atn534 5.7.14 https://support.google.com/mail/bin/answer.py?answer=78754 vq9sm20914609wjc.6 – gsmtp’,
    responseCode: 534 }

    note: I activated the access for less secured apps in gmail and I checked 10 times my login information.

  4. As i am new to node js ,i think following error might be very simple to solve but i dont know how solve it please help me.

    Express Started on Port 3000
    { to: ‘[email protected]’,
    subject: ‘Please confirm your Email account’,
    html: ‘Hello, Please Click on the link to verify your email.Click here to verify’ }
    c:node-email-verification-masternode_modulesnodemailernode_modulessimplesmt
    plibclient.js:918
    this._xoauth2.reconnectCount = 0;
    ^
    TypeError: Cannot assign to read only property ‘reconnectCount’ of false
    at SMTPClient._actionAUTHComplete (c:node-email-verification-masternode_mo
    dulesnodemailernode_modulessimplesmtplibclient.js:918:34)
    at SMTPClient._onData (c:node-email-verification-masternode_modulesnodema
    ilernode_modulessimplesmtplibclient.js:352:29)
    at TLSSocket.emit (events.js:107:17)
    at readableAddChunk (_stream_readable.js:163:16)
    at TLSSocket.Readable.push (_stream_readable.js:126:10)
    at TCP.onread (net.js:529:20)

  5. Thanks in support of sharing such a pleasant thinking, post is nice,
    thats why i have read it fully

  6. This is a very good tip particularly to tthose fresh tto the
    blogosphere. Brief but very accurate info… Appreciate your sharing this one.
    A must read post!

  7. Rand number is stored globally and when one user sends a registration request, it may not be able to confirm the letter, because another user few seconds later will overwrite the value of the variable rand by another registration request. My question is: where should i store rand and other not registered user data?

  8. Instead of storing global rand number, which can be overwritten, i think it would be better to encrypt email and in verify function compare encrypted and original emails (or encrypt email two times with different keys to keep it secret in the link).

  9. Microsoft Windows [Version 6.1.7601]
    Copyright (c) 2009 Microsoft Corporation. All rights reserved.

    C:Userspraveen>f:

    F:>cd “Email Verfication”

    F:Email Verfication>npm install
    npm WARN package.json [email protected] No description
    npm WARN package.json [email protected] No repository field.
    npm WARN package.json [email protected] No README data
    npm WARN package.json [email protected] No license field.
    [email protected] node_modulesexpress
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]2
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected] ([email protected])
    ├── [email protected] ([email protected])
    ├── [email protected] ([email protected])
    ├── [email protected] ([email protected], [email protected])
    ├── [email protected] ([email protected], [email protected], [email protected])
    └── [email protected] ([email protected], [email protected])

    [email protected] node_modulesnodemailer
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected] ([email protected], [email protected], [email protected].3
    1, [email protected])
    ├── [email protected] ([email protected], [email protected])
    ├── [email protected] ([email protected], [email protected], [email protected],
    [email protected])
    └── [email protected] ([email protected], [email protected], [email protected])

    F:Email Verfication>node server.js
    Express Started on Port 3000
    ^C
    F:Email Verfication>node server.js
    Express Started on Port 3000
    ^C
    F:Email Verfication>node server.js
    Express Started on Port 3000
    ^C
    F:Email Verfication>node server.js
    Express Started on Port 3000
    { to: ‘[email protected]’,
    subject: ‘Praveen’,
    text: ‘askfaf’ }
    { [AuthError: Invalid login – 535-5.7.8 Username and Password not accepted. Lear
    n more at
    535 5.7.8 https://support.google.com/mail/answer/14257 pw7sm14673932pbc.4 – gsm
    tp]
    name: ‘AuthError’,
    data: ‘535-5.7.8 Username and Password not accepted. Learn more atrn535 5.7.
    8 https://support.google.com/mail/answer/14257 pw7sm14673932pbc.4 – gsmtp’,
    stage: ‘auth’ }
    ^C
    F:Email Verfication>node server.js
    Express Started on Port 3000
    { to: ‘[email protected]’,
    subject: ‘Praveen’,
    text: ‘It Works but need more changes’ }
    { [AuthError: Invalid login – 534-5.7.14 Please log in via your web browser and
    534-5.7.14 then try again.
    534-5.7.14 Learn more at
    534 5.7.14 https://support.google.com/mail/answer/78754 ez2sm36953968pbb.5 – gs
    mtp]
    name: ‘AuthError’,
    data: ‘534-5.7.14 Please log
    in via your web browser andrn534-5.7.14 then try again.rn534-5.7.14 Learn
    more atrn534 5.7.14 https://support.google.com/mail/answer/78754 ez2sm3695396
    8pbb.5 – gsmtp’,
    stage: ‘auth’ }
    ^C
    F:Email Verfication>npm install
    npm WARN package.json [email protected] No description
    npm WARN package.json [email protected] No repository field.
    npm WARN package.json [email protected] No README data
    npm WARN package.json [email protected] No license field.

    F:Email Verfication>npm install
    npm WARN package.json [email protected] No description
    npm WARN package.json [email protected] No repository field.
    npm WARN package.json [email protected] No README data
    npm WARN package.json [email protected] No license field.
    [email protected] node_modulesexpress
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected] ([email protected])
    ├── [email protected] ([email protected])
    ├── [email protected] ([email protected])
    ├── [email protected] ([email protected], [email protected])
    ├── [email protected] ([email protected], [email protected], [email protected])
    └── [email protected] ([email protected], [email protected])

    [email protected] node_modulesnodemailer
    ├── [email protected]
    ├── [email protected]
    ├── [email protected]
    ├── [email protected] ([email protected], [email protected], [email protected].3
    1, [email protected])
    ├── [email protected] ([email protected], [email protected])
    ├── [email protected] ([email protected], [email protected], [email protected],
    [email protected])
    └── [email protected] ([email protected], [email protected], [email protected])

    F:Email Verfication>node server.js
    Express Started on Port 3000
    { to: ‘[email protected]’,
    subject: ‘Please confirm your Email account’,
    html: ‘Hello, Please Click on the link to verify your email.Click here to verify’ }
    { [AuthError: Invalid login – 535-5.7.8 Username and Password not accepted. Lear
    n more at
    535 5.7.8 https://support.google.com/mail/answer/14257 g12sm37371200pat.36 – gs
    mtp]
    name: ‘AuthError’,
    data: ‘535-5.7.8 Username and Password not accepted. Learn more atrn535 5.7.
    8 https://support.google.com/mail/answer/14257 g12sm37371200pat.36 – gsmtp’,
    stage: ‘auth’ }
    ^C
    F:Email Verfication>node server.js
    Express Started on Port 3000
    { to: ‘[email protected]’,
    subject: ‘Please confirm your Email account’,
    html: ‘Hello, Please Click on the link to verify your email.Click here to verify’ }
    { [AuthError: Invalid login – 534-5.7.14 Please log in via your web browser and
    534-5.7.14 then try again.
    534-5.7.14 Learn more at
    534 5.7.14 https://support.google.com/mail/answer/78754 yg2sm36918473pbb.79 – g
    smtp]
    name: ‘AuthError’,
    data: ‘534-5.7.14 Please log
    in via your web browser andrn534-5.7.14 then try again.rn534-5.7.14 Learn
    more atrn534 5.7.14 https://support.google.com/mail/answer/78754 yg2sm3691847
    3pbb.79 – gsmtp’,
    stage: ‘auth’ }
    ^C
    Hi Shahid,

    I got an error like this
    Express Started on Port 3000
    { to: ‘[email protected]’,
    subject: ‘Please confirm your Email account’,
    html: ‘Hello, Please Click on the link to verify your email.Click here to verify’ }
    { [AuthError: Invalid login – 535-5.7.8 Username and Password not accepted. Lear
    n more at
    535 5.7.8 https://support.google.com/mail/answer/14257 gv1sm36980091pbc.38 – gs
    mtp]
    name: ‘AuthError’,
    data: ‘535-5.7.8 Username and Password not accepted. Learn more atrn535 5.7.
    8 https://support.google.com/mail/answer/14257 gv1sm36980091pbc.38 – gsmtp’,
    stage: ‘auth’ }

  10. Hi Shahid,

    I got an error like this

    html: ‘Hello, Please Click on the link to verify your email.Click here to verify’ }
    { [AuthError: Invalid login – 535-5.7.8 Username and Password not accepted. Lear
    n more at
    535 5.7.8 https://support.google.com/mail/answer/14257 gv1sm36980091pbc.38 – gs
    mtp]
    name: ‘AuthError’,
    data: ‘535-5.7.8 Username and Password not accepted. Learn more atrn535 5.7.
    8 https://support.google.com/mail/answer/14257 gv1sm36980091pbc.38 – gsmtp’,
    stage: ‘auth’ }

  11. Please hlep me.

    { to: ‘[email protected]’,
    subject: ‘Please confirm your Email account’,
    html: ‘Hello, Please Click on the link to verify your email.Click here to verify’ }
    [Error: Authentication required, invalid details provided]

    This is error…. i don’t no …. help me

  12. I’m working with Sails.JS and I have adjusted your code to my modules but I got this error:
    – Message sent: undefined (from the line: console.log(“Message sent: ” + response.message);)

  13. Hi,

    Thanks for the simple tutorial. Just to confirm this is not saving anything in DB like Redis or Mongodb based on TTL? The host and the ID are getting from the local variable. This means the user is still on the same page and not opening the email a day later?

    Thanks again.

    1. Hey there,

      Thanks for pointing it out. I wrote this tutorial long ago and due to time constraint haven’t incorporate the DB part. So your guess is correct, it checks for local variable not something already stored. Will update it soon.

  14. Catch in code, if someone didn’t verify and another user verify first, first user will unable to verify after that.

  15. Hi. have issue :
    { to: ‘[email protected]’,
    subject: ‘Please confirm your Email account’,
    html: ‘Hello, Please Click on the link to verify your email.Click here to verify’ }
    { [AuthError: Invalid login – 535-5.7.8 Username and Password not accepted. Learn more at
    535 5.7.8 https://support.google.com/mail/answer/14257 jk1sm27243071wjb.27 – gsmtp]
    name: ‘AuthError’,
    data: ‘535-5.7.8 Username and Password not accepted. Learn more atrn535 5.7.8 https://support.google.com/mail/answer/14257 jk1sm27243071wjb.27 – gsmtp’,
    stage: ‘auth’ } can you help with this ?

  16. Hi Shahid,

    Your nodemailer tutorial was a great help to me.

    Can you tell me how can I achieve the same with node.js and angularJS instead of jquery

    1. I believe it’s on Node so for Angular you just need to create one controller to accept routes and call the API using $http factory.

      For angular here is the tutorial.

  17. Thanks a lot for this tutorial.
    I’m coding an app using react native. I can send an email wich contains a link with an id, but when I clicked on the link, it can’t return to the app. Do you know how to resolve my problem ?
    Thanks again 🙂

  18. Hi Shahid, great tutorial! I am currently working on taking this a step further, and posting to user info to a noSQL DB (cloudant) as an unauthorized user as soon as they register. The issue I am having is with updating the user type once the account is verified. When i click the verify link, i am redirect to a 404 with the url ending with /verify?106. Do i just need to add a verify view which indicates the authentication went through and says they can sign in? Thanks

    1. You really don’t need a view. You sure it is /verify?106 ? Should be /verify?id=106 or something.

          1. Still nothing. could I possibly send you some of the code so you can see what Ive got going on?

          2. for the most part yes. Like i said, i am trying to work your code into a database post so the user will be saved. But where would you like me to send it to? Thank you for your help

          3. Just zip the code file excluding node_modules folder and send me at shahid[at]codeforgeek.com

  19. Hi shadid i’ve been waiting for almost an hour bust still it says . Sending email .. please wait
    Why is it not working ?

    1. and there’s an error saying
      Error: Authentication required, invalid details provided at SMTPTtransport.sendEmail

  20. Please help me with this error

    subject: ‘Please confirm your Email account’, html: ‘Hello, Please Click on the link to verify your email.Click here to verify’ } /mnt/c/Users/Logesh/Desktop/NodeJSWorks/redisworks/node-email-verification/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:918 this._xoauth2.reconnectCount = 0; ^ TypeError: Cannot assign to read only property ‘reconnectCount’ of false at SMTPClient._actionAUTHComplete (/mnt/c/Users/Logesh/Desktop/NodeJSWorks/redisworks/node-email-verification/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:918:34) at SMTPClient._onData (/mnt/c/Users/Logesh/Desktop/NodeJSWorks/redisworks/node-email-verification/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:352:29) at emitOne (events.js:77:13) at TLSSocket.emit (events.js:169:7) at readableAddChunk (_stream_readable.js:146:16) at TLSSocket.Readable.push (_stream_readable.js:110:10) at TLSWrap.onread (net.js:523:20)

  21. hi,
    I am getting this error

    subject: ‘Please confirm your Email account’,
    html: ‘Hello, Please Click on the link to verify your email.Click here to verify’ }
    /home/gousia/Desktop/node-email-verification-master/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:918
    this._xoauth2.reconnectCount = 0;
    ^

    TypeError: Cannot create property ‘reconnectCount’ on boolean ‘false’
    at SMTPClient._actionAUTHComplete (/Desktop/node-email-verification-master/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:918:34)
    at SMTPClient._onData (/Desktop/node-email-verification-master/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js:352:29)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:191:7)
    at readableAddChunk (_stream_readable.js:176:18)
    at TLSSocket.Readable.push (_stream_readable.js:134:10)
    at TLSWrap.onread (net.js:554:20)
    please help me with this

  22. Express Started on Port 3000

    { to: '[email protected]',
      subject: 'Please confirm your Email account',
      html: 'Hello, Please Click on the link to verify your email.Click here to verify' }
    { AuthError: Invalid login - 534-5.7.14  Please log in via your web browser and
    534-5.7.14 then try again.
    534-5.7.14  Learn more at
    534 5.7.14  https://support.google.com/mail/answer/78754 s3sm40356583pgn.70 - gsmtp
        at SMTPClient._actionAUTHComplete (C:\Users\krish_000\Desktop\node-email-verification-master\node_modules\simplesmtp\lib\client.js:925:23)
        at SMTPClient._onData (C:\Users\krish_000\Desktop\node-email-verification-master\node_modules\simplesmtp\lib\client.js:354:29)
        at emitOne (events.js:96:13)
        at TLSSocket.emit (events.js:189:7)
        at readableAddChunk (_stream_readable.js:176:18)
        at TLSSocket.Readable.push (_stream_readable.js:134:10)
        at TLSWrap.onread (net.js:551:20)
      name: 'AuthError',
      data: '534-5.7.14  Please log in via your web browser and\r\n534-5.7.14 then try again.\r\n534-5.7.14  Learn more at\r\n534 5.7.14  https://support.google.com/mail/answer/78754 s3sm40356583pgn.70 - gsmtp',
      stage: 'auth' }
      1. provided correct credentials only…the main problem was low app permissions. And now i resolved..thank you

  23. When I sending link to my mail which I used in server code everything is fine.When I want to sent verification link to my friend’s mail she is getting the link in her mail but when she hits the link nothing response in both terminal and browser.So how can I fix this issue.

    1. Well, you need to deploy the code to the Server. Your friend machine is probably in different network and Server is running on your computer. That’s why it’s unreachable.

    1. Hi Adrian,

      Sorry for the trouble. The error came due to the update in nodemailer module. I have updated the code and post to meet that requirenment. Re-run npm install command and update the code accordingly, it should work.

  24. This is my error.
    { Error: self signed certificate in certificate chain
    at TLSSocket. (_tls_wrap.js:1105:38)
    at emitNone (events.js:106:13)
    at TLSSocket.emit (events.js:208:7)
    at TLSSocket._finishInit (_tls_wrap.js:639:8)
    at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38) code: ‘ECONNECTION’, command: ‘CONN’ }

  25. Hi, since you don’t recommend math.floor for production, is there anything else you can recommend to accomplish the same task.

  26. Hello I have implemented your code in my signup route. Thank you so much it is working. But how can i checkup no one can login without verifying their email.

    1. You should have a isVerified field in your model in order to change its value from false to true after verification

  27. Hi!
    I downloaded your file and changed sender’s id and pw as u said.
    and then I ran the server (console said Express Started on Port 3000, it means it runs)
    but in Html file, even though i click the send button, nothing happened in my console.
    idk what the problem is…..could u help me?

      1. How?, I mean is there any free services available or how to setup my own, because i need to verify daily upto 100k emails.

          1. ok, But if use that i need to pay 100 of dollars , so is there way to setup own at low cost to verify emails, like that reference website you povided and anyleads.com. that will sve 100 of dollars for me.

  28. Cannot verify the receiver through the click event. It verifies the user and generates id as soon as the mail gets delivered.

  29. I did what you told to do but I am getting TimeOut Error. When I printed it on console I got these, I don`t know what to do please help.
    { Error: connect ETIMEDOUT 74.120.64.108:465
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1097:14)
    errno: ‘ETIMEDOUT’,
    code: ‘ESOCKET’,
    syscall: ‘connect’,
    address: ‘74.120.64.108’,
    port: 465,
    command: ‘CONN’ }
    pls pls help.

      1. Sir, what should I do to solve this problem, I tried to find on google but none of the solutions are working.
        Please help me
        Thanks

      2. When I opened two clients at the same time and verify after that, It gives “Bad Request” for the first and “Email verified” for the second.
        It is not working for the first client. What I should do now

Leave a Reply to venkat Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.