{"id":2011,"date":"2024-09-18T12:00:00","date_gmt":"2024-09-18T10:00:00","guid":{"rendered":"https:\/\/kindsonthegenius.com\/blog\/how-to-authenticate-from-react-to-spring-boot\/"},"modified":"2026-07-05T03:27:00","modified_gmt":"2026-07-05T01:27:00","slug":"how-to-authenticate-from-react-to-spring-boot","status":"publish","type":"post","link":"https:\/\/kindsonthegenius.com\/blog\/how-to-authenticate-from-react-to-spring-boot\/","title":{"rendered":"How to Authenticate From React to Spring Boot \u2013 Part 1"},"content":{"rendered":"<p>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.<\/p>\n<p>Finally, we would configure our React application to authenticate against the Spring Boot API.<\/p>\n<ol>\n<li><a href=\"#t1\">Configure Spring Security at the Backend<\/a><\/li>\n<li><a href=\"#t2\">Implement UserDetailsService<\/a><\/li>\n<li><a href=\"#t3\">Implement UserDetails, Update the Controller and Service<\/a><\/li>\n<li><a href=\"#t6\">Configure CORS<\/a><\/li>\n<li><a href=\"#t4\">Create a New User and Test the Login<\/a><\/li>\n<li><a href=\"#t5\">Setup AxiosConfig to use .env Parameters<\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t1\">1. Configure Spring Security at the Backend<\/strong><\/h4>\n<p>If you have not setup Spring Security in your Spring Boot application, please follow the steps below. You can also watch the <a href=\"https:\/\/youtu.be\/KuzdIOIugJ4?si=UnaANC9n3FadXj9s\" target=\"_blank\" rel=\"noopener\">step by step video tutorial here<\/a>.<\/p>\n<p>However the basic steps are as follows:<\/p>\n<p><strong>Step 1 &#8211; Create the SecurityConfig file and in it, do the following:<\/strong><\/p>\n<ul>\n<li>Create the User model, repository, service and controller<\/li>\n<li>Annotate the class with <em>@Configuration<\/em> and<em> @WebSecurity<\/em> annotations<\/li>\n<li>Configure the <em>SecurityFilterChain<\/em> bean<\/li>\n<li>Create the <em>UserDetails<\/em> bean<\/li>\n<li>Create the <em>BCryptPasswordEncoder<\/em> bean<\/li>\n<li>Create an configure the Authentication provider, setting the UserDetails and password encoder<\/li>\n<\/ul>\n<p><em><strong>The SecurityFilterChain bean is given below:<\/strong><\/em><\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #555555; font-weight: bold;\">@Bean<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> SecurityFilterChain <span style=\"color: #0066bb; font-weight: bold;\">securityFilterChain<\/span><span style=\"color: #333333;\">(<\/span>HttpSecurity httpSecurity<span style=\"color: #333333;\">)<\/span> <span style=\"color: #008800; font-weight: bold;\">throws<\/span> Exception <span style=\"color: #333333;\">{<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">return<\/span> httpSecurity\r\n            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">csrf<\/span><span style=\"color: #333333;\">(<\/span><span style=\"color: #997700; font-weight: bold;\">AbstractHttpConfigurer:<\/span><span style=\"color: #333333;\">:<\/span>disable<span style=\"color: #333333;\">)<\/span>\r\n            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">authorizeHttpRequests<\/span><span style=\"color: #333333;\">(<\/span>auth <span style=\"color: #333333;\">-&gt;<\/span> auth\r\n                            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">requestMatchers<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"\/register\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">permitAll<\/span><span style=\"color: #333333;\">()<\/span>\r\n                            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">requestMatchers<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"\/login\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">permitAll<\/span><span style=\"color: #333333;\">()<\/span>\r\n                            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">anyRequest<\/span><span style=\"color: #333333;\">().<\/span><span style=\"color: #0000cc;\">authenticated<\/span><span style=\"color: #333333;\">()<\/span>\r\n                    <span style=\"color: #333333;\">)<\/span>\r\n            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">httpBasic<\/span><span style=\"color: #333333;\">(<\/span>Customizer<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">withDefaults<\/span><span style=\"color: #333333;\">())<\/span>\r\n            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">build<\/span><span style=\"color: #333333;\">();<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong><em>The Authentication Provider bean is given below:<\/em><\/strong><\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #555555; font-weight: bold;\">@Bean<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> AuthenticationProvider <span style=\"color: #0066bb; font-weight: bold;\">authenticationProvider<\/span><span style=\"color: #333333;\">()<\/span> <span style=\"color: #333333;\">{<\/span>\r\n    DaoAuthenticationProvider provider <span style=\"color: #333333;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> DaoAuthenticationProvider<span style=\"color: #333333;\">();<\/span>\r\n    provider<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setUserDetailsService<\/span><span style=\"color: #333333;\">(<\/span>userDetailsService<span style=\"color: #333333;\">);<\/span>\r\n    provider<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setPasswordEncoder<\/span><span style=\"color: #333333;\">(<\/span>bCryptPasswordEncoder<span style=\"color: #333333;\">());<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">return<\/span> provider<span style=\"color: #333333;\">;<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t2\">Step 2 &#8211; Implement the UserDetailsService<\/strong><\/h4>\n<p>Create a class called MyUserDetailsService that implements UserDetailsService.<\/p>\n<p>Override the loadUserByUsername and update the UserRepository<\/p>\n<p>You will also need to throw an exception is the user is null.<\/p>\n<p>Finally return a <em>UserPrincipal<\/em>(create in Step 3)<\/p>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t3\">Step 3 &#8211; Implement UserDetails, Update the Controller and Service<\/strong><\/h4>\n<p>Create a class UserPrincipal that implements UserDetails.<\/p>\n<p>Add a field User in and add a constructor<\/p>\n<p>Also ensure that the getAuthorities() method returns as shown below:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">return<\/span> Collections<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">singleton<\/span><span style=\"color: #333333;\">(<\/span><span style=\"color: #008800; font-weight: bold;\">new<\/span> SimpleGrantedAuthority<span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"USER\"<\/span><span style=\"color: #333333;\">));<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4><strong>Step 4 &#8211; Configure CORS<\/strong><\/h4>\n<p>We would have to configure Cross Origin Resource Sharing (CORS)\u00a0 to allow access from requests coming from our React application.<\/p>\n<p>Create a CorsConfigurationSource bean as shown below.<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #555555; font-weight: bold;\">@Bean<\/span>\r\nCorsConfigurationSource <span style=\"color: #0066bb; font-weight: bold;\">corsConfigurationSource<\/span><span style=\"color: #333333;\">()<\/span> <span style=\"color: #333333;\">{<\/span>\r\n    CorsConfiguration configuration <span style=\"color: #333333;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> CorsConfiguration<span style=\"color: #333333;\">();<\/span>\r\n    configuration<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setAllowedOrigins<\/span><span style=\"color: #333333;\">(<\/span>List<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">of<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"http:\/\/localhost:3001\"<\/span><span style=\"color: #333333;\">));<\/span>\r\n    configuration<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setAllowedMethods<\/span><span style=\"color: #333333;\">(<\/span>List<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">of<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"GET\"<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"POST\"<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"PUT\"<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"DELETE\"<\/span><span style=\"color: #333333;\">));<\/span>\r\n    configuration<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">setAllowCredentials<\/span><span style=\"color: #333333;\">(<\/span><span style=\"color: #008800; font-weight: bold;\">true<\/span><span style=\"color: #333333;\">);<\/span>\r\n    configuration<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">addAllowedHeader<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"*\"<\/span><span style=\"color: #333333;\">);<\/span>\r\n    UrlBasedCorsConfigurationSource source <span style=\"color: #333333;\">=<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> UrlBasedCorsConfigurationSource<span style=\"color: #333333;\">();<\/span>\r\n    source<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">registerCorsConfiguration<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"\/**\"<\/span><span style=\"color: #333333;\">,<\/span> configuration<span style=\"color: #333333;\">);<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">return<\/span> source<span style=\"color: #333333;\">;<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Next, add this to the SecurityFilterChain<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">cors<\/span><span style=\"color: #333333;\">(<\/span>Customizer<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">withDefaults<\/span><span style=\"color: #333333;\">())<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t4\">Step 5 &#8211;\u00a0 Create New User and Test the Login<\/strong><\/h4>\n<p>Using Postman client, make a POST request to the \/register, specifying the user details in the request body. No Authentication is used.<\/p>\n<p>Then make a GET request to the \/products endpoint and <span style=\"font-family: 'Source Sans Pro', Graphik, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; font-size: 1.125rem;\">using Basic Authentication, enter the username and password<\/span><\/p>\n<p>Now, we need to specify the username and password in <em>axios<\/em> get request. This is specified as the second parameter to the <em>get()<\/em> method.<\/p>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t5\">Step 6 &#8211; Setup AxiosConfig in React Application<\/strong><\/h4>\n<p>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:<\/p>\n<p>1. Create a .env file and place the following inside it. Replace the <strong><em>yourusername<\/em><\/strong> and <strong><em>yourpassword<\/em><\/strong> accordingly<\/p>\n<pre style=\"margin: 0; line-height: 125%;\">REACT_APP_API_USERNAME<span style=\"color: #333333;\">=<\/span>yourusername\r\nREACT_APP_API_PASSWORD<span style=\"color: #333333;\">=<\/span>yourpassword\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>2. Create a file called <em>axiosConfig.js<\/em> and this would be the content<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008800; font-weight: bold;\">import<\/span> axios from <span style=\"background-color: #fff0f0;\">'axios'<\/span>;\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">const<\/span> axiosInstance <span style=\"color: #333333;\">=<\/span> axios.create({\r\n  <span style=\"color: #888888;\">\/\/ You can also add default headers here<\/span>\r\n  headers<span style=\"color: #333333;\">:<\/span> {\r\n    <span style=\"background-color: #fff0f0;\">'Content-Type'<\/span><span style=\"color: #333333;\">:<\/span> <span style=\"background-color: #fff0f0;\">'application\/json'<\/span>\r\n  }\r\n});\r\n\r\naxiosInstance.interceptors.request.use(\r\n  (config) <span style=\"color: #333333;\">=&gt;<\/span> {\r\n    <span style=\"color: #008800; font-weight: bold;\">const<\/span> username <span style=\"color: #333333;\">=<\/span> REACT_APP_API_USERNAME;\r\n    <span style=\"color: #008800; font-weight: bold;\">const<\/span> password <span style=\"color: #333333;\">=<\/span> REACT_APP_API_PASSWORD;\r\n    <span style=\"color: #008800; font-weight: bold;\">if<\/span> (username <span style=\"color: #333333;\">&amp;&amp;<\/span> password) {\r\n      config.auth <span style=\"color: #333333;\">=<\/span> {\r\n        username<span style=\"color: #333333;\">:<\/span> username,\r\n        password<span style=\"color: #333333;\">:<\/span> password\r\n      };\r\n    }\r\n    <span style=\"color: #008800; font-weight: bold;\">return<\/span> config;\r\n  },\r\n  (error) <span style=\"color: #333333;\">=&gt;<\/span> {\r\n    <span style=\"color: #008800; font-weight: bold;\">return<\/span> Promise.reject(error);\r\n  }\r\n);\r\n\r\n<span style=\"color: #008800; font-weight: bold;\">export<\/span> <span style=\"color: #008800; font-weight: bold;\">default<\/span> axiosInstance;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>3. Since we have setup the config, you can now replace all the use of <em>axios<\/em> with <em>axiosInstance<\/em>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pagelayer_contact_templates":[],"_pagelayer_content":"","footnotes":""},"categories":[414],"tags":[],"class_list":["post-2011","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/2011","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/comments?post=2011"}],"version-history":[{"count":1,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/2011\/revisions"}],"predecessor-version":[{"id":2179,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/2011\/revisions\/2179"}],"wp:attachment":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/media?parent=2011"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/categories?post=2011"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/tags?post=2011"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}