How to Authenticate From React to Spring Boot – Part 1

In this tutorial, you will learn how to add Spring Security to your Spring Boot REST API and require authentication to be able to access some routes in the API. Then you well implement User Registration and create users.

Finally, we would configure our React application to authenticate against the Spring Boot API.

  1. Configure Spring Security at the Backend
  2. Implement UserDetailsService
  3. Implement UserDetails, Update the Controller and Service
  4. Configure CORS
  5. Create a New User and Test the Login
  6. Setup AxiosConfig to use .env Parameters

 

1. Configure Spring Security at the Backend

If you have not setup Spring Security in your Spring Boot application, please follow the steps below. You can also watch the step by step video tutorial here.

However the basic steps are as follows:

Step 1 – Create the SecurityConfig file and in it, do the following:

  • Create the User model, repository, service and controller
  • Annotate the class with @Configuration and @WebSecurity annotations
  • Configure the SecurityFilterChain bean
  • Create the UserDetails bean
  • Create the BCryptPasswordEncoder bean
  • Create an configure the Authentication provider, setting the UserDetails and password encoder

The SecurityFilterChain bean is given below:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
    return httpSecurity
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(auth -> auth
                            .requestMatchers("/register").permitAll()
                            .requestMatchers("/login").permitAll()
                            .anyRequest().authenticated()
                    )
            .httpBasic(Customizer.withDefaults())
            .build();
}

 

The Authentication Provider bean is given below:

@Bean
public AuthenticationProvider authenticationProvider() {
    DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
    provider.setUserDetailsService(userDetailsService);
    provider.setPasswordEncoder(bCryptPasswordEncoder());
    return provider;
}

 

Step 2 – Implement the UserDetailsService

Create a class called MyUserDetailsService that implements UserDetailsService.

Override the loadUserByUsername and update the UserRepository

You will also need to throw an exception is the user is null.

Finally return a UserPrincipal(create in Step 3)

 

Step 3 – Implement UserDetails, Update the Controller and Service

Create a class UserPrincipal that implements UserDetails.

Add a field User in and add a constructor

Also ensure that the getAuthorities() method returns as shown below:

return Collections.singleton(new SimpleGrantedAuthority("USER"));

 

Step 4 – Configure CORS

We would have to configure Cross Origin Resource Sharing (CORS)  to allow access from requests coming from our React application.

Create a CorsConfigurationSource bean as shown below.

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(List.of("http://localhost:3001"));
    configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
    configuration.setAllowCredentials(true);
    configuration.addAllowedHeader("*");
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

 

Next, add this to the SecurityFilterChain

.cors(Customizer.withDefaults())

 

Step 5 –  Create New User and Test the Login

Using Postman client, make a POST request to the /register, specifying the user details in the request body. No Authentication is used.

Then make a GET request to the /products endpoint and using Basic Authentication, enter the username and password

Now, we need to specify the username and password in axios get request. This is specified as the second parameter to the get() method.

 

Step 6 – Setup AxiosConfig in React Application

This means we would place the user credentials in a .env file and then configure our application to read the environment variables. Follow the steps below:

1. Create a .env file and place the following inside it. Replace the yourusername and yourpassword accordingly

REACT_APP_API_USERNAME=yourusername
REACT_APP_API_PASSWORD=yourpassword

 

2. Create a file called axiosConfig.js and this would be the content

import axios from 'axios';

const axiosInstance = axios.create({
  // You can also add default headers here
  headers: {
    'Content-Type': 'application/json'
  }
});

axiosInstance.interceptors.request.use(
  (config) => {
    const username = REACT_APP_API_USERNAME;
    const password = REACT_APP_API_PASSWORD;
    if (username && password) {
      config.auth = {
        username: username,
        password: password
      };
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

export default axiosInstance;

 

3. Since we have setup the config, you can now replace all the use of axios with axiosInstance.

User Avatar

kindsonthegenius

Kindson Munonye is currently completing his doctoral program in Software Engineering in Budapest University of Technology and Economics

View all posts by kindsonthegenius →

Leave a Reply

Your email address will not be published. Required fields are marked *