Learnitweb

Login with Github with Spring Boot and React JS

Introduction

In today’s digital landscape, allowing users to log in using their existing Google or GitHub accounts can greatly enhance the user experience while improving security. In this tutorial, we’ll walk you through integrating OAuth2 login with Google and GitHub in a full-stack application using Spring Boot for the backend and React JS for the frontend.

Whether you’re building a personal project or a production-ready app, this guide will help you implement social login seamlessly with minimal effort. By the end, you’ll have a secure authentication flow that enables users to sign in with just a click.

Create a Spring Boot App

The first step is to create a Spring Boot App. Following is our pom.xml. We have used https://start.spring.io/ to create the Spring Boot application.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.4</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.oauth</groupId>
	<artifactId>sample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>sample</name>
	<description>Demo project for Spring Boot OAuth</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-oauth2-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.security</groupId>
			<artifactId>spring-security-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Register a new OAuth application in GitHub

  • Login to the GitHub account.
  • Click on your Profile picture to open the menu “Settings”.
  • Click on “Developer Settings”
  • Click on “OAuth Apps”
  • Click on “New OAuth app” and provide the details for your application.
  • Submit the form by clicking on the “Register application”.
  • On the next screen, generate the client secret by using the button “Generate a new client secret”. Copy the value of Client ID and client secret and save it in some safe place.

Configuring Spring Boot application

In the application.properties file, add the following properties:

#Github OAuth2 Configuration
spring.security.oauth2.client.registration.github.client-id=Ov23lixf9QAugvVnP2af
spring.security.oauth2.client.registration.github.client-secret=7e178ad4524db17dff62959f64a8e79feaf5d2c7
spring.security.oauth2.client.registration.github.client-scope=read:user,user:email

Create a SecurityConfig file:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception{
        http.csrf(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(authorizeRequests -> authorizeRequests.anyRequest().authenticated())
                //.formLogin(form -> form.defaultSuccessUrl("/hello", true));
                .oauth2Login(oauth2 -> oauth2.defaultSuccessUrl("/hello", true));
        return http.build();
    }
}

In this security configuration file, we are defining the success URL. So let’s create this /hello endpoint.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingsController {
    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }
}

Test our changes

Now, let’s test our changes done till now.

Now, try to access the page http://localhost:8080. You should be redirected to the page something like this:

After that you should see the following page:

And once you authorize, you should be redirected to the http://localhost:8080

Creating the UI with React

Your React component will look something like this:

import React from "react";

const Login = () => {
  const handleGithubLogin = () => {
    // Redirect to Spring Boot backend to start GitHub OAuth2 flow
    window.location.href = "http://localhost:8080/oauth2/authorization/github";
  };

  return (
    <div style={{ textAlign: "center", marginTop: "100px" }}>
      <h2>Login Page</h2>
      <button onClick={handleGithubLogin}>Login with GitHub</button>
    </div>
  );
};

export default Login;

How it works

  • When the user clicks the button, they are sent to your Spring Boot backend.
  • Spring Security handles the OAuth2 redirection to GitHub.
  • After successful login, Spring redirects back to your configured redirect URI (like http://localhost:4000/dashboard).

Now, suppose you want to show the logged in user name and email. You can call the /user-info endpoint.

Make sure your Spring Boot backend exposes an endpoint to return user details from the OAuth2 principal.

@RestController
public class UserController {

    @GetMapping("/user-info")
    public Map<String, Object> userInfo(@AuthenticationPrincipal OAuth2User principal) {
        Map<String, Object> userDetails = new HashMap<>();
        userDetails.put("name", principal.getAttribute("name"));
        userDetails.put("email", principal.getAttribute("email"));
        return userDetails;
    }
}

Ensure CORS is Enabled in Spring Boot

To allow frontend (localhost:4000) to access the backend (localhost:8080):

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:4000")
                .allowedMethods("*")
                .allowCredentials(true); // important for sending cookies/session
    }
}

React: Dashboard Component That Calls /user-info

import React, { useEffect, useState } from "react";

const Dashboard = () => {
  const [user, setUser] = useState({ name: "", email: "" });

  useEffect(() => {
    fetch("http://localhost:8080/user-info", {
      method: "GET",
      credentials: "include", // important to send cookies/session
    })
      .then((res) => {
        if (res.ok) return res.json();
        throw new Error("Failed to fetch user info");
      })
      .then((data) => {
        setUser({
          name: data.name,
          email: data.email,
        });
      })
      .catch((err) => {
        console.error(err);
        // Optionally redirect to login if unauthenticated
      });
  }, []);

  return (
    <div style={{ textAlign: "center", marginTop: "50px" }}>
      <h2>Welcome, {user.name}</h2>
      <p>Email: {user.email}</p>
    </div>
  );
};

export default Dashboard;