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.
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:
When you’re all set up and ready, open the project with your favorite IDE. Your directory structure should look something like this:
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:
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
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.example.demo
, 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.
Note!!! All Source Codes are borrowed 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 @Id
annotation is imported from javax.persistence.Id
Now let's also create the AppUserService
and AppUserRepository
in the same package.
The overridden method loadUserByUsername()
in AppUserService
locates 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 BCrypt
as 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
We need to create the RegistrationRequest
class 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.
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
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.
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.
I used @ManyToOne
above appUser
because one user can have many confirmation tokens. Let us implement the service and interface for the confirmation token.
Send Email Confirmation
Let us create a new package called email
and inside this package, we create Interface EmailSender
and EmailService
.
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.
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.
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/
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:
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;