Integrating React with Google OAuth in a .NET Core Backend - Auth

Introduction

Integrating Google OAuth authentication with a .NET Core backend enables secure and convenient user authentication in React applications. This blog post will guide you through the process of setting up Google OAuth authentication in a React frontend and handling authentication tokens in a .NET Core backend.

Set up Google OAuth

  • Go to the Google Cloud Console and create a new project.
  • Navigate to the "OAuth consent screen" tab and configure the required information.
  • In the "Credentials" tab, create OAuth client credentials for a web application.
  • Note down the client ID and client secret generated by Google.

Implement Google OAuth in React

  • Install the react-google-login package using npm or yarn.
  • Use the GoogleLogin component provided by react-google-login in your React application.
  • Configure the component with your Google OAuth client ID.
import React from 'react';
import { GoogleLogin } from 'react-google-login';

const GoogleAuthButton = ({ onSuccess, onFailure }) => {
    return (
        <GoogleLogin
            clientId="YOUR_GOOGLE_CLIENT_ID"
            onSuccess={onSuccess}
            onFailure={onFailure}
            buttonText="Login with Google"
            cookiePolicy={'single_host_origin'}
        />
    );
};

export default GoogleAuthButton;

Handle OAuth response in React

  • Implement callback functions for successful and failed authentication.
  • Retrieve the authentication token from the response and store it in local storage or state for future use.

Secure .NET Core backend

  • Install the Microsoft.AspNetCore.Authentication.Google NuGet package in your .NET Core backend.
  • Configure Google OAuth authentication in the Startup.cs file.
services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
})
.AddCookie()
.AddGoogle(options =>
{
    options.ClientId = "YOUR_GOOGLE_CLIENT_ID";
    options.ClientSecret = "YOUR_GOOGLE_CLIENT_SECRET";
});

Protect backend routes with authentication

  • Add the [Authorize] attribute to controller endpoints that require authentication.
  • Access the authenticated user's information using the HttpContext.User property.

Let's break down the process of integrating Google OAuth authentication with React frontend and .NET Core backend with end-to-end code examples.

React Frontend

First, let's implement Google OAuth authentication in the React frontend.

// GoogleAuthButton.js

import React from 'react';
import { GoogleLogin } from 'react-google-login';

const GoogleAuthButton = ({ onSuccess, onFailure }) => {
    return (
        <GoogleLogin
            clientId="YOUR_GOOGLE_CLIENT_ID"
            onSuccess={onSuccess}
            onFailure={onFailure}
            buttonText="Login with Google"
            cookiePolicy={'single_host_origin'}
        />
    );
};

export default GoogleAuthButton;

In your React component:

import React from 'react';
import GoogleAuthButton from './GoogleAuthButton';

const App = () => {
    const handleSuccess = (response) => {
        console.log('Authentication successful:', response);
        // Send the token to the backend for verification
    };

    const handleFailure = (error) => {
        console.error('Authentication failed:', error);
    };

    return (
        <div>
            <h1>Welcome to My App</h1>
            <GoogleAuthButton onSuccess={handleSuccess} onFailure={handleFailure} />
        </div>
    );
};

export default App;

.NET Core Backend

Next, let's secure our .NET Core backend and handle Google OAuth authentication.

In Startup.cs

// Startup.cs

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
        })
        .AddCookie()
        .AddGoogle(options =>
        {
            options.ClientId = "YOUR_GOOGLE_CLIENT_ID";
            options.ClientSecret = "YOUR_GOOGLE_CLIENT_SECRET";
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();

        app.UseRouting();

        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

With this setup, your React frontend will display a "Login with Google" button, and when clicked, it will trigger the Google OAuth authentication flow. Upon successful authentication, the token can be sent to the .NET Core backend for further processing and authorization. The backend is configured to handle Google OAuth authentication and protect routes with the [Authorize] attribute, ensuring that only authenticated users can access protected resources.

Let's create a simple controller with authorization in .NET Core and explain how it works with the above setup.

// MyController.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Controllers
{
    [Authorize] // Requires authentication for all actions in this controller
    public class MyController : Controller
    {
        // GET: /My
        public IActionResult Index()
        {
            return View();
        }

        // GET: /My/SecureAction
        public IActionResult SecureAction()
        {
            return View();
        }
    }
}

Explanation

  1. [Authorize] attribute is applied at the controller level, which means all actions within this controller require authentication.
  2. When a request is made to any action within MyController, the middleware checks if the user is authenticated.
  3. If the user is not authenticated, they are redirected to the authentication endpoint (in this case, Google OAuth login).
  4. Once authenticated, the user is redirected back to the application with a token.
  5. The token is then validated by the authentication middleware.
  6. If the token is valid, the user is authorized to access the requested action.
  7. If the user is not authorized (e.g., does not have the necessary role or claim), they may be redirected to an error page or receive a 403 Forbidden response.

This way, the [Authorize] attribute helps secure controller actions by requiring users to authenticate before accessing them, ensuring that only authorized users can access sensitive or protected resources.

Conclusion

Integrating Google OAuth authentication with a React frontend and .NET Core backend provides a seamless and secure authentication mechanism for your web applications. By following the steps outlined in this blog post, you can enable users to log in with their Google accounts and access protected resources in your application.