Hey there, fellow developers! If you're diving into the world of web development and eager to learn how to build a secure login system, you've come to the right place.
In this step-by-step guide, I'll walk you through the process of creating a login form using two powerful technologies: Spring Boot for the backend magic and React for the frontend charm.
A user-friendly login interface where your users can securely access your application. Exciting, right? Well, buckle up as we embark on a coding adventure together!
By the end of this guide, you'll have a fully functional login form that seamlessly connects your Spring Boot backend with your React frontend.
No need to worry if you're new to these technologies – I'll break it down into simple steps and share some insights along the way.
So, let's get started login and registration form in React JS with Spring boot and turn that login page dream into a reality!
Visit Spring Initializer and configure your project with the following dependencies:
- Spring JPA
- Spring Web
- Spring Security
- MySQL
Add the specified dependencies to your pom.xml
file.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependencies>
Configure the MySQL database connection in the application.properties
file. This is the pivotal location where Spring Boot establishes a connection to the MySQL database.
application.properties
spring.application.name=Registation
server.port=8085
spring.jpa.hibernate.ddl-auto=create
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/dbkms?createDatabaseIfNotExist=true
spring.datasource.username=root
spring.datasource.password=root123
#jpa vendor adapter configuration
spring.jpa.database-platform=org.hibernate.dialect.MySQL57Dialect
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
Create an Employee
entity representing employee data in the database.
Employee
package com.example.Registation.Entity;
import javax.persistence.*;
@Entity
@Table(name="employee")
public class Employee {
@Id
@Column(name="employee_id", length = 45)
@GeneratedValue(strategy = GenerationType.AUTO)
private int employeeID;
@Column(name="employee_name", length = 255)
private String employeeName;
@Column(name="email", length = 255)
private String email;
@Column(name="password", length = 255)
private String password;
public Employee() {
}
public Employee(int employeeID, String employeeName, String email, String password) {
this.employeeID = employeeID;
this.employeeName = employeeName;
this.email = email;
this.password = password;
}
After that, Implement DTOs (EmployeeDTO
and LoginDTO
) for data transfer between frontend and backend.
EmployeeDTO
public class EmployeeDTO {
private int employeeID;
private String employeeName;
private String email;
private String password;
public EmployeeDTO() {
}
public EmployeeDTO(int employeeID, String employeeName, String email, String password) {
this.employeeID = employeeID;
this.employeeName = employeeName;
this.email = email;
this.password = password;
}
}
LoginDTO
public class LoginDTO {
private String email;
private String password;
public LoginDTO() {
}
public LoginDTO(String email, String password) {
this.email = email;
this.password = password;
}
Create a EmployeeRepository
interface extending JpaRepository
for database operations.
EmployeeRepo
package com.example.Registation.Repo;
import com.example.Registation.Entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@EnableJpaRepositories
@Repository
public interface EmployeeRepo extends JpaRepository<Employee,Integer>
{
Optional<Employee> findOneByEmailAndPassword(String email, String password);
Employee findByEmail(String email);
}
Now, create Services. Add the below code to that file.
EmployeeService
package com.example.Registation.Service;
import com.example.Registation.Dto.EmployeeDTO;
import com.example.Registation.Dto.LoginDTO;
import com.example.Registation.payload.response.LoginMesage;
public interface EmployeeService {
String addEmployee(EmployeeDTO employeeDTO);
LoginMesage loginEmployee(LoginDTO loginDTO);
}
Implement an EmployeeService
interface and its corresponding implementation (EmployeeIMPL
).
EmployeeIMPL
package com.example.Registation.Service.impl;
import com.example.Registation.Dto.EmployeeDTO;
import com.example.Registation.Dto.LoginDTO;
import com.example.Registation.Entity.Employee;
import com.example.Registation.Repo.EmployeeRepo;
import com.example.Registation.Service.EmployeeService;
import com.example.Registation.payload.response.LoginMesage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Optional;
@Service
public class EmployeeIMPL implements EmployeeService {
@Autowired
private EmployeeRepo employeeRepo;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public String addEmployee(EmployeeDTO employeeDTO) {
Employee employee = new Employee(
employeeDTO.getEmployeeID(),
employeeDTO.getEmployeeName(),
employeeDTO.getEmail(),
this.passwordEncoder.encode(employeeDTO.getPassword())
);
employeeRepo.save(employee);
return employee.getEmployeeName();
}
EmployeeDTO employeeDTO;
@Override
public LoginMesage loginEmployee(LoginDTO loginDTO) {
String msg = "";
Employee employee1 = employeeRepo.findByEmail(loginDTO.getEmail());
if (employee1 != null) {
String password = loginDTO.getPassword();
String encodedPassword = employee1.getPassword();
Boolean isPwdRight = passwordEncoder.matches(password, encodedPassword);
if (isPwdRight) {
Optional<Employee> employee = employeeRepo.findOneByEmailAndPassword(loginDTO.getEmail(), encodedPassword);
if (employee.isPresent()) {
return new LoginMesage("Login Success", true);
} else {
return new LoginMesage("Login Failed", false);
}
} else {
return new LoginMesage("password Not Match", false);
}
}else {
return new LoginMesage("Email not exits", false);
}
}
}
Create an EmployeeController to manage the Restful API requests related to employee login and registration.
Develop an EmployeeController
to manage RESTful API requests for employee login and registration.
EmployeeController
package com.example.RegisterLogin.EmployeeController;
import com.example.RegisterLogin.Dto.EmployeeDTO;
import com.example.RegisterLogin.Dto.LoginDTO;
import com.example.RegisterLogin.Service.EmployeeService;
import com.example.RegisterLogin.response.LoginResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@CrossOrigin
@RequestMapping("api/v1/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@PostMapping(path = "/save")
public String saveEmployee(@RequestBody EmployeeDTO employeeDTO)
{
String id = employeeService.addEmployee(employeeDTO);
return id;
}
@PostMapping(path = "/login")
public ResponseEntity<?> loginEmployee(@RequestBody LoginDTO loginDTO)
{
LoginResponse loginResponse = employeeService.loginEmployee(loginDTO);
return ResponseEntity.ok(loginResponse);
}
}
Set up a SecurityConfig
class for password encoding.
package com.example.Registation.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Create a LoginMesage
class for displaying messages during testing.
LoginResponse
public class LoginMesage {
String message;
Boolean status;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public LoginMesage(String message, Boolean status) {
this.message = message;
this.status = status;
}
}
Frontend with React
Install React using npx create-react-app
.
npx create-react-app front-end
Install necessary dependencies for API requests: axios
and react-router-dom
.
npm install --save axios
npm i react-router-dom
Style your application using Bootstrap. Copy the Bootstrap CSS and paste it into index.html
.
Create three components: Home.jsx
, Register.jsx
, and Login.jsx
.
Register.jsx
import { useState } from "react";
import axios from "axios";
function Register() {
const [employeename, setEmployeename] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
async function save(event) {
event.preventDefault();
try {
await axios.post("http://localhost:8085/api/v1/employee/save", {
employeename: employeename,
email: email,
password: password,
});
alert("Employee Registation Successfully");
} catch (err) {
alert(err);
}
}
return (
<div>
<div class="container mt-4" >
<div class="card">
<h1>Student Registation - Vidvatek</h1>
<form>
<div class="form-group">
<label>Employee name</label>
<input type="text" class="form-control" id="employeeName" placeholder="Enter Name"
value={employeeName}
onChange={(event) => {
setEmployeeName(event.target.value);
}}
/>
</div>
<div class="form-group">
<label>email</label>
<input type="email" class="form-control" id="email" placeholder="Enter Email"
value={email}
onChange={(event) => {
setEmail(event.target.value);
}}
/>
</div>
<div class="form-group">
<label>password</label>
<input type="password" class="form-control" id="password" placeholder="Enter password"
value={password}
onChange={(event) => {
setPassword(event.target.value);
}}
/>
</div>
<button type="submit" class="btn btn-primary mt-4" onClick={save} >Save</button>
</form>
</div>
</div>
</div>
);
}
export default Register;
Login.jsx
import { useState } from "react";
import { useNavigate } from 'react-router-dom';
import axios from "axios";
function Login() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const navigate = useNavigate();
async function login(event) {
event.preventDefault();
try {
await axios.post("http://localhost:8085/api/v1/employee/login", {
email: email,
password: password,
}).then((res) =>
{
console.log(res.data);
if (res.data.message == "Email not exits")
{
alert("Email not exits");
}
else if(res.data.message == "Login Success")
{
navigate('/home');
}
else
{
alert("Incorrect Email and Password not match");
}
}, fail => {
console.error(fail); // Error!
});
}
catch (err) {
alert(err);
}
}
return (
<div>
<div class="container">
<div class="row">
<h2>Login - vidvatek.com</h2>
<hr/>
</div>
<div class="row">
<div class="col-sm-6">
<form>
<div class="form-group">
<label>Email</label>
<input type="email" class="form-control" id="email" placeholder="Enter Name"
value={email}
onChange={(event) => {
setEmail(event.target.value);
}}
/>
</div>
<div class="form-group">
<label>password</label>
<input type="password" class="form-control" id="password" placeholder="Enter Fee"
value={password}
onChange={(event) => {
setPassword(event.target.value);
}}
/>
</div>
<button type="submit" class="btn btn-primary" onClick={login} >Login</button>
</form>
</div>
</div>
</div>
</div>
);
}
export default Login;
Home.jsx
function Home() {
return (
<div>
<h1>Home</h1>
</div>
);
}
export default Home;
Configure routes in App.js
using react-router-dom
.
import { BrowserRouter,Routes,Route } from "react-router-dom";
import Register from "./compontents/Register";
import Login from "./compontents/Login";
import Home from "./compontents/Home";
function App() {
return (
<div>
<BrowserRouter>
<Routes>
<Route path="/home" element= { <Home/>} />
<Route path="/register" element= { <Register/>} />
<Route path="/" element= { <Login/>} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
Now you have a robust backend and a responsive frontend for your login system. Follow these steps, and you'll soon have a fully functional login form in your Spring Boot and React application.
Happy coding! 🚀
You might also like:
- Read Also: How to Create Autocomplete Select Options Angular 17
- Read Also: How To Export CSV File In Laravel 10 Example
- Read Also: How to Create Autocomplete Search in React
- Read Also: Laravel 10 React Auth Scaffolding Example