So many websites uses registration by email. Email registration is easy and economical also than registration with mobile phones. Now we will see how to do this stuff with Java, jQuery and MySQL.
Things which I have used
- JDK 8
- Tomcat 8
- JQuery
- Bootstrap for jQuery
- MySql
- Eclipse
Project
I have created this project for explaining Login, Email Registration, Change Password, Forgot Password functionalities. You need to download the project for better understanding
Project set-up
This is simple eclipse project, You can import as existing eclipse project. It needs email server to send registration emails to users. So you have to set-up your own email server
Open Setup.java and update below fields
public static final String DB_URL = "jdbc:mysql://localhost:3306/demos"; public static final String DB_USERNAME = "root"; public static final String DB_PASSWORD = "your root user password"; public static final String MAIL_USERNAME = "mail id here"; // like example@outlook.com public static final String MAIL_PASSWORD = "password here"; // your mail password here public static final String MAIL_SMTP_HOST = "smtp password here"; // smtp.live.com public static final String MAIL_REGISTRATION_SITE_LINK = "http://localhost:8080/demos/VerifyRegisteredEmailHash";
Setup Loggers
Go to WEB-INF folder. Open log4j.properties file. Give logs file path at below line
log4j.appender.Appender2.File=/var/lib/logs/demos.log
Lets build database
Here creating one table is enough. Find below for table create statement
CREATE TABLE `demo_user` ( `user_id` bigint(20) NOT NULL AUTO_INCREMENT, `email` varchar(100) NOT NULL, `first_name` varchar(20) NOT NULL, `last_name` varchar(20) NOT NULL, `email_verification_hash` varchar(45) DEFAULT NULL, `email_verification_attempts` int(11) DEFAULT NULL, `status` varchar(15) DEFAULT 'new', `created_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `password` varchar(45) DEFAULT NULL, PRIMARY KEY (`user_id`), UNIQUE KEY `email_UNIQUE` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='User Table';
Flow of the program
- User Enter Required details ( Email, Password...etc )
- Create User Account, keep status as "new", create Account activation hash code
- Send Account Activation Link with hash code to Registered Email
- User will click on activation link. Now hash code will be submitted to server
- Get the hash code from database. Check this hash code with User registered hash code
- If hash code matches, Update User Account status as "active" , else Increment verification attempts by 1
- If verification attempts reaches 20, then regenerate verification code and resend activation link to user registered email
Database Queries
Find below for database queries which are useful for Email registration
// To know whether email already registered or not select * from DEMO_USER where EMAIL = ? // To create new account insert into DEMO_USER (EMAIL,FIRST_NAME,LAST_NAME,EMAIL_VERIFICATION_HASH,PASSWORD) values (?,?,?,?,?) // To verify Email verification hash code select * from DEMO_USER where USER_ID = ? and EMAIL_VERIFICATION_HASH = ? // To update user account status update DEMO_USER set STATUS = ? where USER_ID = ? // To update email verification attempts update DEMO_USER set EMAIL_VERIFICATION_ATTEMPTS = EMAIL_VERIFICATION_ATTEMPTS + 1 where USER_ID = ? // To select email verification attempts SELECT EMAIL_VERIFICATION_ATTEMPTS from DEMO_USER // To update email verification hash update DEMO_USER set EMAIL_VERIFICATION_HASH = ?, EMAIL_VERIFICATION_ATTEMPTS = ? where USER_ID = ?
Front end
I built HTML pages with jQuery, Bootstrap, Validator.js. Its hard to explain everything here, so please download the project. Basic input fields looks like below code. Here we are taking 4 input values from users
<form class="form-horizontal" id="formRegister" data-toggle="validator" role="form"> <div class="form-group"> <label for="inputEmail" class="control-label">Email</label> <input name="inputEmail" pattern="^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$" class="form-control" id="inputEmail" placeholder="Enter Email" data-error="Enter valid Email" required> <div class="help-block with-errors"></div> </div> <div class="form-group"> <label for="inputFirstName" class="control-label">First Name</label> <input pattern="[A-Za-z0-9]{1,20}" name="inputFirstName" class="form-control" id="inputFirstName" placeholder="Enter First Name" data-error="First name should not be null. It should be less than 20 characters. Use only A-Z, a-z, 0-9 charecters" required> <div class="help-block with-errors"></div> </div> <div class="form-group"> <label for="inputLastName" class="control-label">Last Name</label> <input pattern="[A-Za-z0-9]{1,20}" name="inputLastName" class="form-control" id="inputLastName" placeholder="Enter Last Name" data-error="last name should not be null. It should be less than 20 characters. Use only A-Z, a-z, 0-9 charecters" data-toggle="tooltip" data-placement="right" required> <div class="help-block with-errors"></div> </div> <div class="form-group"> <label for="inputPassword" class="control-label">Password</label> <input type="password" pattern="[A-Za-z0-9@#$%!^&*]{6,30}" name="inputPassword" class="form-control" id="inputPassword" placeholder="Enter Password" data-error="Password should not be null. It should be greater than 6 and less than 30 characters . Use only A-Z, a-z, 0-9, @ # $ % ! ^ & * charecters" required> <div class="help-block with-errors"></div> </div> <div class="form-group"> <label for="inputPassword1" class="control-label">Confirm Password</label> <input type="password" name="inputPassword1" class="form-control" id="inputPassword1" data-match="#inputPassword" placeholder="Enter Password Again" data-error="It should not be null and should match with above password" required> <div class="help-block with-errors"></div> </div> <div class="form-group"> <button style="width:100%" type="submit" class="btn btn-default btn-primary">Register</button> </div> </form>
RegisterEmail.java
This servlet is responsible is for taking inputs from user and creating account for users and sending verification emails
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.mail.MessagingException; import com.sl.dao.UserDAO; import com.sl.db.DBException; import com.sl.model.StatusPojo; import com.sl.model.UserPojo; import com.sl.util.BCrypt; import com.sl.util.GlobalConstants; import com.sl.util.MailUtil; import com.sl.util.Utils; /** * Servlet implementation class RegisterEmail */ @WebServlet("/RegisterEmail") public class RegisterEmail extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public RegisterEmail() { super(); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // collect all input values String email = request.getParameter("inputEmail"); String firstName = request.getParameter("inputFirstName"); String lastName = request.getParameter("inputLastName"); String password = request.getParameter("inputPassword"); UserPojo up = new UserPojo(); up.setEMAIL(email); up.setFIRST_NAME(firstName); up.setLAST_NAME(lastName); // generate hash for password up.setPASSWORD(BCrypt.hashpw(password,GlobalConstants.SALT)); // generate hash code for email verification String hash = Utils.prepareRandomString(30); // generate hash for password up.setEMAIL_VERIFICATION_HASH(BCrypt.hashpw(hash, GlobalConstants.SALT)); StatusPojo sp = new StatusPojo(); String output = ""; try { // check whether email exists or not if(!UserDAO.isEmailExists(email)) { // create account if email not exists String id = UserDAO.insertRow(up); // send verification email MailUtil.sendEmailRegistrationLink(id, email, hash); sp.setCode(0); sp.setMessage("Registation Link Was Sent To Your Mail Successfully. Please Verify Your Email"); output = Utils.toJson(sp); } else { // tell user that the email already in use sp.setCode(-1); sp.setMessage("This Email was already registered"); output = Utils.toJson(sp); } } catch (DBException|MessagingException e) { e.printStackTrace(); sp.setCode(-1); sp.setMessage(e.getMessage()); output = Utils.toJson(sp); } // send output to user PrintWriter pw = response.getWriter(); pw.write(output); pw.flush(); pw.close(); } }
MailUtil.java
public static void sendEmailRegistrationLink(String id, String email, String hash) throws AddressException, MessagingException { Properties props = new Properties(); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.host", Setup.MAIL_SMTP_HOST); props.put("mail.smtp.port", "587"); Session session = Session.getInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(Setup.MAIL_USERNAME, Setup.MAIL_PASSWORD); } }); String link = Setup.MAIL_REGISTRATION_SITE_LINK+"?scope=activation&userId="+id+"&hash="+hash; StringBuilder bodyText = new StringBuilder(); bodyText.append("<div>") .append(" Dear User<br/><br/>") .append(" Thank you for registration. Your mail ("+email+") is under verification<br/>") .append(" Please click <a href=\""+link+"\">here</a> or open below link in browser<br/>") .append(" <a href=\""+link+"\">"+link+"</a>") .append(" <br/><br/>") .append(" Thanks,<br/>") .append(" SodhanaLibrary Team") .append("</div>"); Message message = new MimeMessage(session); message.setFrom(new InternetAddress(Setup.MAIL_USERNAME)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email)); message.setSubject("Email Registration"); message.setContent(bodyText.toString(), "text/html; charset=utf-8"); Transport.send(message); }
In this file, you can find code for sending email verification to user
VerifyRegisteredEmailHash.java
This servlet is responsible for verifying email, activating user accounts
import java.io.IOException; import javax.mail.MessagingException; import javax.mail.internet.AddressException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.sl.dao.UserDAO; import com.sl.db.DBException; import com.sl.model.UserPojo; import com.sl.util.BCrypt; import com.sl.util.GlobalConstants; import com.sl.util.MailUtil; import com.sl.util.Utils; /** * Servlet implementation class VerifyRegisteredEmailHash */ @WebServlet("/VerifyRegisteredEmailHash") public class VerifyRegisteredEmailHash extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public VerifyRegisteredEmailHash() { super(); } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // get user Id and email verification code Hash code String userId = request.getParameter("userId"); String hash = BCrypt.hashpw(request.getParameter("hash"), GlobalConstants.SALT); String scope = request.getParameter("scope"); String message = null; try { // verify with database if(UserDAO.verifyEmailHash(userId, hash) && scope.equals(GlobalConstants.ACTIVATION)) { //update status as active UserDAO.updateStaus(userId, "active"); message = "Email verified successfully. Account was activated. Clic <a href=\"login.html\">here</a> to login"; } else { //now increment verification attempts int attempts = UserDAO.incrementVerificationAttempts(userId); if(attempts == 20) { // reset verification code if attempts equal to 20 String hashcode = Utils.prepareRandomString(30); UserDAO.updateEmailVerificationHash(userId, BCrypt.hashpw(hashcode, GlobalConstants.SALT)); UserPojo up = UserDAO.selectUSER(userId); MailUtil.sendEmailRegistrationLink(userId, up.getEMAIL(), hashcode); message = "20 times Wrong Email Validation Input Given. So we are sent new activation link to your Email"; } else { message = "Wrong Email Validation Input"; } } } catch (DBException e) { e.printStackTrace(); message = e.getMessage(); } catch (AddressException e) { message = e.getMessage(); e.printStackTrace(); } catch (MessagingException e) { message = e.getMessage(); e.printStackTrace(); } if(message!=null) { request.setAttribute(GlobalConstants.MESSAGE, message); request.getRequestDispatcher("/messageToUser.jsp").forward(request, response); } } }
Hi Thanks for the tutorial its awesome But i am getting error of communication failure Whats wrong
ReplyDeletei am using outlook mail to send registration mails here, some times its blocking mails from programme
Deletehi srinivas
ReplyDeleteSame issues of communication failure to me also ,I downloaded projects and copied files to my current projects in eclipse .but when running the project and while doing registration its showing me database exception failure ....I am using same outlook email of mine help me .
however I scrolled your blog and its wonderful....
add e.printStackTrace() to catch blocks of UserDAO.java, trace the exception and share the same
DeleteThis will be the Error Occuring For Me please give me a Solution For this Problem
ReplyDeleteError: 534-5.7.9 Application-specific password required. Learn more at 534 5.7.9 https://support.google.com/accounts/answer/185833 x67sm87045386pff.47 - gsmtp
we probably trying to send mail through a gmail account in which you've enabled 2-factor authentication. A 6-digit authentication token we have to create through which account or gmail id we are going to use that mail application . Google Authenticator app is required to proceed.we have to create for our gmail account . Alternatively, we can generate app-specific passwords through Google's web based ui and use that user name and the generated password to our web application.
ReplyDeleteError :
ReplyDeleteDEBUG 2016-10-10 15:13:07,926 [http-nio-1515-exec-27] com.sl.emailRegistration.RegisterEmail - 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 yi2sm2779237pab.17 - gsmtp
where to find log file path
ReplyDeleteunder var/....
DeleteDEBUG 2017-03-30 13:41:14,396 [http-bio-8080-exec-12] com.sl.dao.UserDAO - Data truncation: Data too long for column 'email_verification_hash' at row 1
ReplyDeleteDEBUG 2017-03-30 13:41:14,400 [http-bio-8080-exec-12] com.sl.emailRegistration.RegisterEmail - Excepion while accessing database
i am getting
ReplyDeleteDEBUG 2017-10-03 18:55:40,689 [http-nio-8081-exec-1]Could not connect to SMTP host: smtp.XXXXX.com, port: 587
its throwing me error :
ReplyDeleteERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'log4j2.debug' to show Log4j2 internal initialization logging.
T
please help
how i set log file path . i tired so many times i didn't find anything.?
ReplyDeleteAny Organization or Individual, claiming to have received a fraudulent mail from a well established organization, should be made to send a copy of the fraudulent mail for verification. email validation
ReplyDeleteSo, you can easily pin banners and offers on it. So, people can easily find your board and you may generate some leads and grow your email list from there.
ReplyDeleteEmail List for Marketing
I recently came across your blog and have been reading along. I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. Nice blog. I will keep visiting this blog very often. ActiveCampaign Pricing
ReplyDeleteI can see that you are an expert at your field! I am launching a website soon, and your information will be very useful for me.. Thanks for all your help and wishing you all the success in your business. email search tool
ReplyDeletethank you for this such a good information about hotmail email login on www.hotmail.com
ReplyDeleteThanks for an interesting blog.
ReplyDeletehotmail
I was surfing the Internet for information and came across your blog. I am impressed by the information you have on this blog. It shows how well you understand this subject. Visit the website link here
ReplyDeleteWhat about input validations?
ReplyDeletegoogle photos login
The best Surf Camp in Morocco. Fun and adventure in one of the best surf spots in the world
ReplyDeleteThe Surf Camp in Morocco.
hello there just love this blog keep updating more:
ReplyDeleteCopper pipe Dubai
Thanks for sharing informative content…Find noida software company to know more and Contact us on given no.…
ReplyDelete