How to build a login and registration with email verification using Java and Spring Framework

Hello readers, Today in this article you’ll learn how to build a full registration system with login and verification where we are going to implement this application using Java and Spring framework with MySQL as a database.

Let's first take a look at the diagram which I borrowed from Amigoscode.

Login & Signup Form with Email Verification diagram [1]

In this project, I'm going to use the Kanban board which is an agile project management method that helps us to manage and streamline workflows to maximize efficiency. The Kanban project board consists of multiple columns which are nothing but workflows. These workflows represent the different project status, In Analysis — Ready For Development — In Development — Ready for Test — In Test — Done. You can add any number of workflows you want to a particular project. In this project, we will keep it simple and use only 3 columns, Todo, In Progress, and Complete.

Bootstrap the project

Let us initialize the Spring boot application. I personally find https://start.spring.io/ a convenient way to get started, so I’m going to go ahead and generate a Maven Spring Boot application, with some dependencies. Your Spring boot initialize should look like this:

Screenshot from https://start.spring.io/ showing Spring Boot project specifications.

When you’re all set up and ready, open the project with your favorite IDE. Your directory structure should look something like this:

project inside the IDE

MySQL Database

If you want to use Postgres instead then follow AmigosCode video. For connecting to the MySQL database, you will need to go to the folder src->main->resources. Rename application. properties to application.yml. In this file, we will put the configuration for the database connection to the MySQL database which you should have install from https://dev.mysql.com/downloads/mysql/. The application.yml should look like this:

Source Code from AmigosCode GitHub repo

If you are not sure how to get MySQL installed/worked then follow this youtube tutorial https://youtu.be/n1zT1OZcgnw.

Open the terminal and login into your MySQL with commando

mysql -u root -p
MySQL

Now let us create a user and database for this project by typing the command

create database registration;

Then type show databases; to show again the database list, you should see like this:

Email Server

We need an email server to test later our project, there is a nice email server that we can use, it's written in Node. Make sure you have node installed in your computer, in terminal just type

npm install -g maildev
maildev

You should get like this

The SMTP server port must be the as inapplication.yml port.

Now we are done with setting up the project with an email server and database, let us take a look at our Kanban board.

Creating the App User

Let us go to our project structure and in the package name com.maherriyadh.com, create another package called appuser which will have an enum called AppUserRole and a class AppUser, in this class, we will implement the interface UserDetails from spring security which is used in order to look up the username, password, and GrantedAuthorities for any given user. and we are going to have a couple of things in these classes.

Source Code from AmigosCode GitHub repo
Source Code from AmigosCode GitHub repo

In Spring Security, granted authorities and roles are a form of expressing a privilege/permission for an authenticated user. When using a Role directly, such as through an expression like hasRole(“ADMIN”), we are restricting access in a coarse-grained manner.

As you see in the AppUser.java Nilson from AmigosCode used @SequenceGenerator I would also choose this because it is my preferred way to generate primary key values and uses a database sequence to generate unique values.sequenceName is the name of the sequence in the DB. We need to specify allocationSize which needs to be the same value that the DB sequence uses as its "auto increment". Very important that The @Idannotation is imported from javax.persistence.Id

Now let's also create the AppUserService and AppUserRepository in the same package.

Source Code from AmigosCode GitHub repo
Source Code from AmigosCode GitHub repo

The overridden method loadUserByUsername() in AppUserServicelocates the user by the username, in our case, the username is the email we should query for. There are a few encoding mechanisms supported by Spring Security and for this project, we’ll use BCryptas it’s usually the best solution available. Most of the other mechanisms, such as the MD5PasswordEncoder and ShaPasswordEncoder use weaker algorithms and are now deprecated.

By extending JpaRepository we get a bunch of generic CRUD methods into our type that allows saving AppUser, deleting them, and so on. Second, this will allow the Spring Data JPA repository infrastructure to scan the classpath for this interface and create a Spring bean for it.

Creating the User Registration

Let's create another package and we will call it registration and create a class there called RegistrationController with two methods and path

Source Code from AmigosCode GitHub repo

We need to create the RegistrationRequestclass in the same package so when the client sends a request then we need to capture a few things. I will create the token confirmation class later in this project.

Source Code from AmigosCode GitHub repo

Now we are done with creating our App User and User Registration, let us update our Kanban board.

Security package

Inside the security package createPassowrdEncoder class and insideSecurity package, we are going to create another package called config and inside it, we will create a class called WebSecurityConfig

Source Code from AmigosCode GitHub repo
Source Code from AmigosCode GitHub repo

In WebSecuirtyConfig class, @EnableWebSecurity is used for spring security java configuration. Add this annotation @configuration on top of your security java class that extends WebSecurityConfigurerAdapter. Override the configure(HttpSecurity http). This is the replacement of XML based configurations like and. This way you can limit requested URLs coming from specific URLs also enable form based log in. antMatcher() tells Spring to only configure HttpSecurity if the path matches this pattern. permitAll() will configure the authorization so that all requests are allowed on that particular path. Spring Security provides a variety of options for performing authentication. The standard and most common implementation is the DaoAuthenticationProvider which retrieves the user details from a simple, read-only user DAO. csrf() stand for Cross-Site Request Forgery and Forgery mean the action of firing a copy or imitation of a document, signature, banknote, or work of art. Let us see this image to help us understand what it is.

Photo by Imperva

Token

Inside registration package let us create another package called token in this package, for this token, we want to store it in the database, so let us create a class called ConfirmationToken and we are going to have a couple of things in this class.

Source Code from AmigosCode GitHub repo

I used @ManyToOneabove appUserbecause one user can have many confirmation tokens. Let us implement the service and interface for the confirmation token.

Source Code from AmigosCode GitHub repo
Source Code from AmigosCode GitHub repo

Send Email Confirmation

Let us create a new package called email and inside this package, we create Interface EmailSender and EmailService .

Source Code from AmigosCode GitHub repo
Source Code from AmigosCode GitHub repo

Let us update our Kanban board after completing some tasks.

Registration Service

Let us now do some business logic whether the email is valid or not and then if it’s valid then we just invoke the app user service to sign up the user. Lets us first create a EmailValidator class in the registration package.

Source Code from AmigosCode GitHub repo

Predicates in Java are implemented with interfaces. Predicate<T> is a generic functional interface representing a single argument function that returns a boolean value.

Let us now create our RegistrationService class and we are going to have a couple of things in this class.

Source Code from AmigosCode GitHub repo

Let us Test our application with Postman

First, make sure you have all classes need for this project, you can also clone the project from AmigosCode repo. Setup Postman on your computer.

Navigate to the project folder or in the ide do

mvn clean install

and then go to the ProjectApplication.java and run the application to get the server started at localhost and also start the email server in node, by typing commandomaildev in terminal as I showed you how in the beginning of this project about Email Server.

Open the Postman application and type the information in Body as JSON with POST request, it should look like this:

You should get a token back when click on Send, also email confirmation, if you navigate to http://0.0.0.0:1080/

http://0.0.0.0:1080/
After clicking on Activate Now

We can also check the token information in the database. Open terminal and login into MySQL and use registration database to show all tables. Like following:

List of tables
User info and confirmation info
http://localhost:8080/login

That’s it, well done for reaching the end.

Acknowledgment

Special thanks to Amigoscode for his amazing video on youtube that helped me a lot with building this project. Take a look at his tutorial/explanation here. https://youtu.be/QwQuro7ekvc

Here is a Github repository from AmigosCode combining all the things we did above.

References

[1]: Amigoscode . (January 17 2021). Java Tutorial — Complete User Login and Registration Backend + Email Verification https://youtu.be/QwQuro7ekvc

— Maher;

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store