Spring Boot React User Registration and Login Example Tutorial

author : Sai K

In this tutorial, we will create a full-stack application using Spring Boot for the backend and React (using

functional components and hooks) for the frontend. We will implement user registration and login functionalities

using Spring Security 6+ and React 18. The tutorial will cover setting up the project, configuring Spring Security,

creating a Spring Boot REST API for user registration and login, and building a React application for the same.

We will also use Bootstrap for styling.


Prerequisites

Before we start, ensure you have the following:

  • Java Development Kit (JDK) installed

  • Apache Maven installed

  • Node.js and npm installed

  • An IDE (such as IntelliJ IDEA, Eclipse, or VS Code) installed

Step 1: Setting Up the Spring Boot Project

1.1 Create a Spring Boot Project

1. Open Spring Initializr:

  • Go to Spring Initializr in your web browser.

  • 2. Configure Project Metadata:

    • Project: Maven Project

    • Language: Java

    • Spring Boot: Select the latest version of Spring Boot

    • Group: com.example

    • Artifact: spring-boot-react-auth

    • Name: spring-boot-react-auth

    • Description: Full Stack Application with Spring Boot and React for User Registration and Login

    • Package Name: com.example.springbootreactauth

    • Packaging: Jar

    • Java Version: 17 (or your preferred version)

    • Click Next.

    3. Select Dependencies:

  • On the Dependencies screen, select the dependencies you need. For user authentication, you can start with:
    • Spring Web

    • Spring Security

    • Spring Data JPA

    • H2 Database

    • Spring Boot DevTools

  • Click Next.
  • 4. Generate the Project:

    • Click Generate to download the project zip file.

    • Extract the zip file to your desired location.

    5. Open the Project in Your IDE:

    • Open your IDE and import the project as a Maven project.

    1.2 Project Structures

    After importing the project, you will see the following structure in your IDE:

    
        spring-boot-react-auth
    ├── src
    │   ├── main
    │   │   ├── java
    │   │   │   └── com
    │   │   │       └── example
    │   │   │           └── springbootreactauth
    │   │   │               ├── SpringBootReactAuthApplication.java
    │   │   │               ├── config
    │   │   │               ├── controller
    │   │   │               ├── model
    │   │   │               ├── repository
    │   │   │               └── service
    │   ├── main
    │   │   └── resources
    │   │       ├── application.properties
    │   └── test
    │       └── java
    │           └── com
    │               └── example
    │                   └── springbootreactauth
    │                       └── SpringBootReactAuthApplicationTests.java
    └── pom.xml
    

    Step 2: Creating the Backend

    2.1 Configure H2 Database

    Open the application.properties file located in the src/main/resources directory and add the following

    configuration:

    
    # H2 Database configuration
    spring.datasource.url=jdbc:h2:mem:testdb
    spring.datasource.driverClassName=org.h2.Driver
    spring.datasource.username=sa
    spring.datasource.password=password
    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
    spring.h2.console.enabled=true
    
    # JPA settings
    spring.jpa.hibernate.ddl-auto=update
    spring.jpa.show-sql=true
    

    2.2 Create the User Entity

    In the model package, create a new Java class named User:

    
        package com.example.springbootreactauth.model;
    
    import jakarta.persistence.Entity;
    import jakarta.persistence.GeneratedValue;
    import jakarta.persistence.GenerationType;
    import jakarta.persistence.Id;
    
    @Entity
    public class User {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
        private String firstName;
        private String lastName;
        private String email;
        private String password;
        private String role;
    
        // Getters and Setters
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getFirstName() {
            return firstName;
        }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getRole() {
            return role;
        }
    
        public void setRole(String role) {
            this.role = role;
        }
    }
    

    2.3 Create the UserRepository Interface

    In the repository package, create a new Java interface named UserRepository:

    
        package com.example.springbootreactauth.repository;
    
    import com.example.springbootreactauth.model.User;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    @Repository
    public interface UserRepository extends JpaRepository {
        User findByEmail(String email);
    }
    

    2.4 Create the UserService Interface

    In the service package, create a new Java interface named UserService:

    
        package com.example.springbootreactauth.service;
    
    import com.example.springbootreactauth.model.User;
    
    public interface UserService {
        User findByEmail(String email);
        User saveUser(User user);
    }
    

    2.5 Implement the UserService Interface

    In the service package, create a new Java class named UserServiceImpl:

    
        package com.example.springbootreactauth.service;
    
    import com.example.springbootreactauth.model.User;
    import com.example.springbootreactauth.repository.UserRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserServiceImpl implements UserService {
    
        private final UserRepository userRepository;
        private final PasswordEncoder passwordEncoder;
    
        @Autowired
        public UserServiceImpl(UserRepository userRepository, PasswordEncoder passwordEncoder) {
            this.userRepository = userRepository;
            this.passwordEncoder = passwordEncoder;
        }
    
        @Override
        public User findByEmail(String email) {
            return userRepository.findByEmail(email);
        }
    
        @Override
        public User saveUser(User user) {
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            return userRepository.save(user);
        }
    }
    

    2.6 Configure Spring Security

    Create a new Java class named SecurityConfig in the config package:

    
        package com.example.springbootreactauth.config;
    
    import com.example.springbootreactauth.model.User;
    import com.example.springbootreactauth.service.UserServiceImpl;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.authentication.AuthenticationManager;
    import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.core.userdetails.UserDetailsService;
    import org.springframework.security.core.userdetails.UsernameNotFoundException;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.web.SecurityFilterChain;
    
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig {
    
        private final UserServiceImpl userService;
    
        public SecurityConfig(UserServiceImpl userService) {
            this.userService = userService;
        }
    
        @Bean
        public UserDetailsService userDetailsService() {
            return email -> {
                User user = userService.findByEmail(email);
                if (user == null) {
                    throw new UsernameNotFoundException("User not found");
                }
                return org.springframework.security.core.userdetails.User
                        .withUsername(user.getEmail())
                        .password(user.getPassword())
                        .roles(user.getRole())
                        .build();
            };
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    
        @Bean
        public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
            return authenticationConfiguration.getAuthenticationManager();
        }
    
        @Bean
        public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            http.csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(authorizeRequests ->
                    authorizeRequests.requestMatchers("/api/register", "/api/login").permitAll()
                        .anyRequest().authenticated()
                )
                .httpBasic();
            return http.build();
        }
    }
    

    2.7 Create the UserController Class

    In the controller package, create a new Java class named UserController:

    
        package com.example.springbootreactauth.controller;
    
    import com.example.springbootreactauth.model.User;
    import com.example.springbootreactauth.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    
    
    @RequestMapping("/api")
    public class UserController {
    
        private final UserService userService;
        private final PasswordEncoder passwordEncoder;
    
        @Autowired
        public UserController(UserService userService, PasswordEncoder passwordEncoder) {
            this.userService = userService;
            this.passwordEncoder = passwordEncoder;
        }
    
        @PostMapping("/register")
        public String register(@RequestBody User user) {
            User existingUser = userService.findByEmail(user.getEmail());
            if (existingUser != null) {
                return "Email already exists";
            }
            userService.saveUser(user);
            return "User registered successfully";
        }
    
        @PostMapping("/login")
        public String login(@RequestBody User user) {
            User existingUser = userService.findByEmail(user.getEmail());
            if (existingUser != null && passwordEncoder.matches(user.getPassword(), existingUser.getPassword())) {
                return "Login successful";
            } else {
                return "Invalid credentials";
            }
        }
    }
    

    Step 3: Creating the Frontend with React

    3.1 Set Up React Project

    1.Open a terminal and navigate to your workspace directory.

    2.Create a new React project using Create React App:

    npx create-react-app react-frontend

    3.Navigate to the project directory:

    cd react-frontend

    3.2 Install Axios and React Router DOM

    Install Axios to make HTTP requests and React Router DOM for routing:

    npm install axios react-router-dom@6

    3.3 Install Bootstrap

    Install Bootstrap for styling:

    npm install bootstrap

    3.4 Create Components

    Create the necessary components for the user registration and login functionalities.

    3.4.1 Create AuthService.js

    Create a new file AuthService.js in the src directory to handle API requests:

    
    import axios from 'axios';
    
    const API_BASE_URL = "http://localhost:8080/api";
    
    class AuthService {
        register(user) {
            return axios.post(`${API_BASE_URL}/register`, user);
        }
    
        login(credentials) {
            return axios.post(`${API_BASE_URL}/login`, credentials);
        }
    }
    
    export default new AuthService();
     

    3.4.2 Create RegisterComponent.js

    Create a new file RegisterComponent.js in the src/components directory:

    3.4.3 Create LoginComponent.js

    Create a new file LoginComponent.js in the src/components directory:

    3.4.4 Create DashboardComponent.js

    Create a new file DashboardComponent.js in the src/components directory:

    
    import React from 'react';
    
    const DashboardComponent = () => {
        return (
            

    Dashboard

    Welcome to the dashboard!

    ); }; export default DashboardComponent;

    3.4.5 Create App.js

    Modify the App.js file to set up routing for the application:

    Step 4: Running the Application

    4.1 Run the Spring Boot Application

    1.Open the SpringBootReactAuthApplication class in the src/main/java/com/example/springbootreactauth

    directory.


    Click the green Run button in your IDE or use the terminal to run theapplication:

    ./mvnw spring-boot:run

    4.2 Run the React Application

    1.Open a terminal and navigate to the react-frontend directory.

    2.Start the React application:

    npm start

    3.Open your web browser and navigate to http://localhost:3000.

    You can now use the registration and login functionalities provided by the React frontend and Spring Boot

    backend.


    Conclusion

    In this tutorial, we created a full-stack application using Spring Boot for the backend and React (with functional

    components and hooks) for the frontend. We implemented user registration and login functionalities using Spring

    Security 6+ and created a simple registration and login page with React. This setup provides a solid foundation

    for developing more complex full-stack applications with user authentication.


    Related Spring and Spring Boot Tutorials/Guides: