DEV Community

Cover image for How to Sign-In with Google in Angular and use JWT based ASP.NET Core C# API Authentication (RSA)
Christian Zink
Christian Zink

Posted on • Updated on • Originally published at levelup.gitconnected.com

How to Sign-In with Google in Angular and use JWT based ASP.NET Core C# API Authentication (RSA)

This guide shows you all the steps to build an Angular SPA with a focus on authentication. The single-page web application uses Sign-In with google and angularx-social-login. The .NET Core authentication backend creates asymmetrically signed tokens to access another REST-API. The sample is fully working and can be the basis for a microservice-like architecture.

Authentication workflow and involved components:

Background and Structure of this Guide

When I wanted to create this kind of application I found many descriptions showing some part of it. This guide brings the parts together. It is structured so you can optionally test every step before continuing to the next.

This guide focuses on the key aspects. I link to other articles for details and download locations of the tools. I use Visual Studio Community for ASP.NET Core 3.1 development.

Contents

  1. Create the Angular App

  2. Add the Login Functionality

  3. Authentication API in the .NET Core Backend

  4. Use the Authentication API

  5. Use the Access Token to Call the Service API

  6. Final Thoughts and Outlook


1. Create the Angular App

Download and install Node.js/NPM.

Create the folder C:\dev and open a command prompt.

Install Angular (I used Angular 9 when writing this guide):

C:\dev>npm install -g @angular/cli
Enter fullscreen mode Exit fullscreen mode

Create the app:

C:\dev>ng new SampleAuthentication
Enter fullscreen mode Exit fullscreen mode

Install the angularx social login module

C:\dev>npm install angularx-social-login
Enter fullscreen mode Exit fullscreen mode

(Optional) Test the app

Start the app and open it in your browser to see if everything is working:

C:\dev>ng serve
Enter fullscreen mode Exit fullscreen mode

Further reading: Understanding Angular and Creating Your First Application


2. Add the Login Functionality

Get a client ID from google

Create a configuration for your app in the google developer console. And add the URL of the Angular debug server (http://localhost:4200) as “Authorised JavaScript origin”:

Get the app’s Client ID that google created for you. Copy the client ID. You will need it in further steps of this guide.

Configure the social login module

Use your google client ID and activate the social login module in the providers section of the app.module.ts:

The code above also adds the HttpClient module, which will be needed later in this guide.

Further reading: Google authentication in Angular

Create the Login Code

Edit app.component.ts

Edit app.component.html

(Optional) Test the login

Start the app

c:\dev>ng serve
Enter fullscreen mode Exit fullscreen mode

Open the app URL in your browser, click “Sign in with google” to open the login dialogue. Sign in with your google credentials:

You are now logged in:

Use the debugger of the chrome browser to get the idToken and other information:

Google creates a new idToken on every login. The token is only valid for a short time.

Copy the idToken. You will need it in the next step of this guide if you want to manually test the API.


3. Authentication API in the .NET Core Backend

The authentication API will use the idToken from google and verify it. Then it creates an access token that grants access to the other APIs of your app.

You will have to increase security before you run this code in a production environment: Shorter token lifetime and refreshs, maybe use sessions instead of tokens, etc.

Install Visual Studio Community (it’s free) with the ASP.NET and web development workload. Create an ASP.NET Core Web API project.

Verification of the idToken

Use the Visual Studio package manager to install the google Auth Package:
Install-Package Google.Apis.Auth

Create an API to verify the idToken.

Change the value in settings.Audience to your google client ID, that you created in the first step of this guide:

The call to GoogleJsonWebSignature.ValidateAsync will throw in case of an error. The Authenticate method uses the JwtGeneratorclass to create and return a custom access token.

Create Custom Access Tokens in .NET Core Using Asymmetric Signatures

With asymmetric JWT signing, only the authentication service knows the private key. The authentication service uses the private key to sign the access token and other APIs use only the public key to verify the access token.

Add the JwtGenerator class, that generates the token:

The JwtGenerator uses the private key, that it gets passed from the UserController. Add the key to appsettings.json, where the UserControler reads it from.

You can use my private key for testing but you will have to create your own private-public key pair for production use. You will also have to adjust token lifetime, etc. for production use.

*Further reading: JWT Authentication with Asymmetric Encryption using certificates in ASP.NET Core. *This story also shows how to create your own public-private key pair.

Edit Startup.cs, which configures the ASP.NET Core backend to use the config, allow access from the Angular client, etc.:


4. Use the Authentication API

Configure the .NET Core API project in debug mode on HTTPS port 5001:

Start the authentication API in Visual Studio:

(Optional) Manually access the authentication API

Use postman to access the API at: https://localhost:5001/user/authenticate

Post the idToken, that you copied from the Chrome debugger in the second step of this guide:

Call the authentication API from the app

Use the Angular HttpClient to post the idToken to the authentication API. Modify app.component.ts:

  • Line 5: Import the HttpClient

  • Lines 21: Send the idToken

(Optional) Test the workflow in the app

Do the same as in the first step of this guide.

Start the app

c:\dev>ng serve
Enter fullscreen mode Exit fullscreen mode

Login and use the debugger and logging in the chrome browser to verify that calling the backend and receiving the generated access token is working:

Copy the access token if you want to do a manual test in the next step of this guide.


5. Use the Access Token to Call the Service API

The access token from the authentication API will grant access to this new service API.

Create an ASP.NET Core Web API project and configure it in debug mode on HTTPS port 5002:

Add a controller:

Edit Startup.cs. It took me a while to configure the validation of the token. The public key to the corresponding private key of the authentication API is used to validate the token. The hard part was to inject the public key. See the comments in the source code for details:

(Optional) Use postman to access the service API

Use postman to access the service API via HTTP GET at: https://localhost:5002/secured

In the previous part of this guide, you copied the access token in the Chrome debugger. Add it as bearer token to the call:

The Final step of this guide: Use the app to access the service API

Modify app.component.ts to post the access key to the service API:

You successfully accessed the protected service API:


6. Final Thoughts and Outlook

Your app is now fully working! But it is only a sample application and you will have to clean up the code and apply security best practices, maybe use a more secure OAuth flow, use Angular and .NET Core design patterns, error handling, etc. to use it in production. And you need your own private-public key pair (see JWT Authentication with Asymmetric Encryption using certificates in ASP.NET Core by
Eduard Stefanescu).

You can add other providers like facebook or your own account database.
See also my follow-up stories:

Please contact me if you have any questions, ideas, or suggestions.

Top comments (3)

Collapse
 
aakashsethi profile image
Aakash Sethi

Hey Christian, thanks for the great write-up!

I was able to follow along easily and understood it well. I do have a few questions though that maybe you could answer if you have some time?

  1. Is it recommended to have a separate authentication service API? I'm familiar with microservices architecture, but for a project small enough, is it a good idea to create the authentication flow in that singular API?

  2. Should we initiate it social authentication from the client always or could I do it from the backend API? Say I just place a button on the frontend, "Sign In with Google" which just calls an API method on the backend to initiate the auth flow. How would that work? I'm thinking of doing this so that I can keep all the ClientID and Client Secret (for Google, Facebook, Spotify, etc.) hidden away from the client and tucked away somewhere safe in my backend server/secret vault.

Collapse
 
christianzink profile image
Christian Zink

Hello Aakash,

Thank you for your feedback.

I will try to answer your questions. But these are only my personal oppinions so you should do your own researches, too.

  1. I would use a single microservice that handles everything regarding users and authentication. Like login with google, facebook, (optional) user signup and user database, creation of application JWTs. etc

  2. From a security perspective there is no reason to hide the clientID from the user. But handling the flow in the backend would be a security improvement for other reasons. The OAuth flow in the backend is called "Authorization Code Flow" and it will be more secure. But I did not try it myself yet.

Collapse
 
parthen profile image
Seyhan Bakır • Edited

Thanks for your article. Good trick to set audience , because a lot of people forget to check it.
btw i like the schema that in first image , it is very helpful.