Implementing OAuth Sign-in with Angular and Spring Boot: A Step-by-Step Guide

OAuth2 for sign-in or sign-up enhances security by minimizing credential exposure and offers convenience through single sign-on with popular platforms like Google or Facebook. It ensures granular access control, scalability, and compliance with industry standards, reducing development effort with readily available libraries. Users benefit from streamlined registration and enhanced privacy, while developers gain insights and analytics for improved decision-making. Overall, OAuth2 simplifies authentication, enhances user experience, and fosters interoperability across various applications and services.


Discover how to enhance your web application's security by implementing OAuth sign-in with Angular and Spring Boot. This comprehensive step-by-step guide walks you through the process of integrating OAuth authentication seamlessly between your frontend and backend. Learn how to leverage Angular's robust framework for the frontend user interface, while harnessing Spring Boot's powerful features for backend authentication. With clear instructions and practical examples, this blog empowers developers to implement OAuth sign-in efficiently.

1. Project flow


terminal log showing a spring boot application startup


Oauth - Watch Video



2. Prerequisites

  1. Angular 17 or above
  2. Java 17 or above
  3. Springboot 3 or above

3. Creating client-id and client-secret keys

  1. go to console.cloud.google.com
  2. from the listed services choose API & Services
  3. select Credentials on the leftside navbar
  4. on the top nav bar click on CREATE CREDENTIALS
  5. choose OAuth Client ID
  6. fill the necessary details
  7. at the last step you will receive client-id and client-secret

  8. save these two details we gonna need them while setting up our backed service

4. Setting-up backend

application.properties

        server.port=8080
        spring.application.name=oauth-backend

        spring.security.oauth2.client.registration.google.client-id=#your_client_id
        spring.security.oauth2.client.registration.google.client-secret=#your_client_secret
          

pom.xml

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
          

OAuthController

        package com.vivek.oauthbackend.controller;

        import org.springframework.http.HttpStatus;
        import org.springframework.http.ResponseEntity;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;

        import java.net.URI;

        /**
         * @author viveksoni
         */

        @RestController
        @RequestMapping("/OAuth")
        public class OAuthController {

            @GetMapping("/signInOAuthGoogle")
            private ResponseEntity googleLogin() {
                return ResponseEntity.status(HttpStatus.FOUND)
                        .location(URI.create("/oauth2/authorization/google"))
                        .build();
            }
        }
          

CallbackController

        package com.vivek.oauthbackend.controller;

        import jakarta.servlet.http.HttpSession;
        import org.springframework.http.HttpStatus;
        import org.springframework.http.ResponseEntity;
        import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        import org.springframework.security.core.Authentication;
        import org.springframework.security.core.context.SecurityContextHolder;

        /**
         * @author viveksoni
         */

        @RestController
        @RequestMapping(name = "/callback")
        public class CallbackController {

            @GetMapping(name = "/oauth/ggl")
            public ResponseEntity<String> googleAuthCallback(HttpSession session) {
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                if (authentication != null && authentication.getPrincipal() instanceof DefaultOAuth2User) {
                    DefaultOAuth2User oauth2User = (DefaultOAuth2User) authentication.getPrincipal();
                    String email = oauth2User.getAttribute("email");
                    return ResponseEntity.ok("Received Google OAuth2 callback for email: " + email);
                } else {
                    return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Google authentication failed");
                }
            }
        }
          

5. Setting-up frontend

create a new project using ng new #project_name

add the following form on your app.component.html, you can create new login component if you wish to, i'm however adding my form directly on app component only.

        <main class="main">
          <div class="content mt-5">
            <div class="row justify-content-center">
              <div class="col-md-6">
                <form>
                  <div class="mb-3">
                    <label for="username" class="form-label">Username</label>
                    <input type="text" class="form-control" id="username" placeholder="Enter your username" disabled>
                  </div>
                  <div class="mb-3">
                    <label for="password" class="form-label">Password</label>
                    <input type="password" class="form-control" id="password" placeholder="Enter your password" disabled>
                  </div>
                  <button type="submit" class="btn btn-primary mb-3" disabled>Submit</button>
                  <div class="mb-3">
                    <a type="button" class="btn btn-outline-danger" (click)="callOauthGoogleAPI()">
                      <img src="./assets/img/icons/google.svg"> Sign in with Google
                    </a>
                  </div>
                </form>
              </div>
            </div>
          </div>
        </main>

        <router-outlet></router-outlet>
          

form should look like this:

OAuth Login form


if not, please check with bootstrap installed or not


calling backend api /OAuth/signInOAuthGoogle on click event on 'Sign in with Google' button


app.component.ts

      import { Component } from '@angular/core';
      import { CommonModule } from '@angular/common';
      import { RouterOutlet } from '@angular/router';

      /**
       * @author viveksoni
       */

      @Component({
        selector: 'app-root',
        standalone: true,
        imports: [CommonModule, RouterOutlet],
        templateUrl: './app.component.html',
        styleUrl: './app.component.css'
      })
      export class AppComponent {
        title = 'oauth-frontend';

        callOauthGoogleAPI() {
          console.log('clicked!');
          window.location.href = 'http://localhost:8080/OAuth/signInOAuthGoogle';
        }
      }
        

note: we can not call google authentication server's api directly from frontend, it will give us cors error.

Conclusion

This blog covers a very basic functionality of Open Authentication using Google, same way we can integrate Open Authentication for various social media platform such as facebook, or github. We can create our own Open Authentication Server. The use case of OAuth is very wide. Further we can enhance our application by extracting tokens and user details from Authentication object and use them as per the business requirements, for an instance saving the user details in DB or retrieving them.


source code

Get in touch

Let’s work together

Reach out if you have a concept for a website or mobile app or require guidance with product design. contact me.
  info@whywhytechnova.com
  +(91) 88661 28862