React and Google OAuth with .NET Core backend

Atul Shukla
mickeysden
Published in
5 min readOct 22, 2018
“grayscale photography of two children sitting on ledge” by Joshua Clay on Unsplash

Overview

I was inspired to write this article because we rarely find React or Angular posts with .NET Core backend as examples, and I am sure, like me, there are several developers using this combination tech stack for their products.

Social Authentication being a very common use case, I felt was a good example to demonstrate how to structure such an app. This is a very opinionated (my way) of setting this code base.

Finally, I would like mention that I have used the workflow defined in this article, and used this post as a baseline example to work from.

Code

If you wish to skip the post and get to the code, you can access it here https://github.com/mickeysden/dotnet-core-react-oauth-example (updated to .NET Core 3.1)

Architecture

As mentioned in the post by Google, the following is the application flow we will be working towards:

Google Sign-in for server-side apps

Client: This is the client application, built in Reactjs (web) in our example

Server: This is the server backend that we will build using .NET Core 2

Google API Server and OAuth 2.0 Dialog: These are services build by Google that we will be using

The workflow, as described by Google, is a hybrid one where a user authorizes your app on the client side using the Google JavaScript API client, and you send a special one-time authorization code to your server. Your server exchanges this one-time-use code to acquire its own access and refresh tokens from Google for the server to be able to make its own API calls, which can be done while the user is offline (if needed).

Setup Google Developer Console

The first step is to setup API access for Google for you app (if you haven’t already done so). The steps are straightforward and documented in several posts. I like what @alexanderleon has posted in this article and I will simply provide a link to it.

Setup .NET Core Webapi backend

I am assuming that you have some experience with .NET Core WebApi. There are several tutorials out there, but you can get started here.

Basic steps I followed on Debian

  • Step 1: Create a folder (in my case named backend) and change into the folder
  • Step 2: Run command to create a new .NET Core WebApi project
$ dotnet new webapi
  • Step 3: Add packages for Google.Apis.Auth, Newtonsoft.Json, Serilog (optional) and Serilog.Sinks.Console (optional)
$ dotnet add package Google.Apis.Auth
$ dotnet add package Newtonsoft.Json
$ dotnet add package Serilog
$ dotnet add package Serilog.Sinks.Console

Serilog is a great logging framework that provides a more flexible logging on top of the default .NET Core logging

  • Step 4: Modify Program.cs as follows

As you will notice in the above code, a logged is activated at the start of the program, along with loading the contents of the appsettings.json file into a static object.

  • Step 5: Modify Startup.cs as follows

The methods ConfigureServices and Configure have been modified to include Jwt Authentication to the web api.

  • Step 6: Database — in the example I have not used a database but created a service (IAuthService.cs) to store data in memory. This can easily be modified to use a MySQL or MongoDb (or any other personal favorite data store) implementation.

You will notice in the Authenticate implementation I pass a GoogleJsonWebSignature object. More on this below.

  • Step 7: Controller — this is where the business logic will flow through. As depicted on Step 4, in the Google auth image above, once the client gets a successful one-time token from Google, it will pass this token to the backend server that we are building. I have defined the endpoint for this to be https://<server-url>/v1/auth/google and here is the controller code for this.

As you see in the controller method above, a POST request is sent to the endpoint, where the payload consists of a JSON with the Google returned one-time tokenid attached.

Once the token is received, it is verified by the backend server by calling GoogleJsonWebSignature.ValidateAsync method from the Google Auth API. Once validated, this is then internally authenticated to find if the user exists, and if not create it. This all happens in the AuthService implementation described above.

Once a user object is created, it is used to return a JWT token back to the client for future bearer authentication with the backend server.

Setup React frontend with Redux and React-Router

The frontend is created using the create-react-app tool.

$ create-react-app frontend && cd frontend
$ npm install react-google-login react-redux react-router-dom redux redux-logger redux-thunk jsonwebtoken
$ cd src
$ mkdir actions components containers reducers services

Follow these steps next:

  • Step 1: Create authActions

The login action passes the token as a payload to the reducer, but the logout action doesn’t.

  • Step 2: Create reducer

Upon login, we are simply storing the payload, which is the JWT returned from our server.

  • Step 3: Create service to validate if token is active (this is needed to make sure the Bearer we have locally is active)
  • Step 4: Update App.js to setup routing and call Login and Logout containers

As you will see, this is a bare bones react app with dummy components for Home, About and NotFound pages. These will be customized to your app (if you need them). The Login and Logout containers are where the authentication heavy lifting is happening.

You will also notice that I am using CSS items from the bootstrap framework. I have not called these out, as this would ideally be dependent on the layout of your application.

  • Step 5: Implement Login.js

As you see, the code checks if the user is authenticated, if not, we send it to google servers to do so. Once authenticated from the Google servers, the token received is sent to our callback server we created above. Once we get a successful token from our server, the login action is dispatched and redux takes over.

Keep in mind to use the withRouter method by React-Router v4. This smoothed things with Redux.

  • Step 6: Implement Logout.js

Logout is simpler than login. The inbuilt componentWillMount() is called to dispatch a logout on redux.

  • Step 7: Tie it all together

Finally, everything is tied up in index.js initializing the redux store and then calling Router.

Hopefully this post and the code gave you an idea of how a .NET Core WebApi server can be used as backend for a React app, specially in the case of social authentication. Please let me know your thoughts on reading and any coding experiences you have on this.

--

--

Atul Shukla
mickeysden

Husband, Father, family man and Code Philosopher