Secure Angular Site using JWT Authentication with ASP.NET Core Web API

Last Updated on June 20, 2023 by Aram

In this tutorial, we will learn how to secure Angular site using JWT Authentication with ASP.NET Core Web API.

The angular site will include a login, signup, tasks and profile screens, the site will be secured using JWT Authentication with Access and Refresh tokens built using ASP.NET Core Web API in .NET 6.

We will use one of my previous tutorials where we already built a Tasks Database using SQL Server Express and connected it with ASP.NET Core Web API through Entity Framework Core. The API includes endpoints with GET, POST, PUT, DELETE http methods.

You can follow my previous tutorial Apply JWT Access Tokens and Refresh Tokens in ASP .NET Core Web API 6 to fully understand how you can secure your APIs with JWT, but for this tutorial we will only need the APIs to be up-and-running and connected to the Tasks Database.

So just complete the database preparation part then clone the final project TasksApi from my GitHub account and continue with this tutorial.

Next, run the TasksAPI project, that you have just cloned, you should be getting the following Swagger page:

Now you have the API part ready, let’s start building the front-end part using Angular 2+.

Starting the tutorial to Secure Angular Site using JWT Authentication

Angular App

Angular is a front-end TypeScript framework that enables you to build cutting-edge mobile and desktop web applications in the form of SPA (Single-Page Applications)

As of writing this tutorial, the latest version of Angular is 13. You can check this page to review and check for any updates on Angular.

Before developing our Angular site, we need to setup our development environment with the prerequisites of Angular.

Visual Studio Code

This is the most popular and best IDE for developing front-end web apps, including Angular. It has everything you need to crush your way into building wonderful apps.

Make sure it is installed at your side through this link. Then install the ‘Angular Language Service’ extension, as you can see below:

This extension will boost your development speed with code completion and other refactoring options.

Node.js

We will need node.js for 2 main reasons:

  1. To run NPM (Node Package Manager) commands that will allow you to install libraries and packages that are needed for the angular development, one of which is the Angular CLI; This is the command line interface that enables you to run the commands needed for creating different the building blocks and deploying the angular code to localhost server.
  2. node.js is a server-side framework which means it can be used to create a localhost to host your angular code on it. At the end you require some hosting server to put your front-end files on it (html, css, js and others).

So let’s go and install node.js.

Since we are using windows desktop to do our development, then it is recommended to follow this approach to install node.js on your machine

NVM

nvm is the Node Version Manager that allows you to install node.js in the most correct and proper way. Since we are on windows, it is best to use nvm-windows installer, so let’s download and install it.

Once installed, open a cmd or powershell, and type> nvm ls , you should get the below response

Then we will need to see what we should install through the command> nvm list available

It is recommended to install the LTS version, since it is a Long-Term Support version being more stable than the latest release.

Therefore, as of writing this tutorial, the current LTS version is 16.14.0, which is the version that we are going to install now.

Go ahead and type> nvm install 16.14.0

It will download and install node.js 16.14.0

Then you can type > nvm ls to get the install version, notice that you can have multiple node.js installations and this is what nvm is useful for, it allows you to easily switch between different node.js installations to support you for multiple projects.

Now the final step is to let nvm use the installation version as your current installation by typing> nvm use 16.14.0

see here we are getting access denied, because this requires admin permissions, so let’s close cmd and run it as admin from windows start

So let’s see if node is now working fine, type> node -v

You should get the current version of node:

NPM

This is the node package manager, which allows you install and manage the libraries and dependencies of your angular app.

Once you install node.js, npm should be there by default, but let’s make sure it is actually there and check its version.

Open Visual Studio Code, then from the Terminal tab, choose New Terminal, from the right side, open the options menu and choose Command Prompt:

Navigate to your designated folder that you will create your angular project on.

Let’s make sure the npm is installed, type> npm -v

Angular CLI

Now let’s start by installing the Angular CLI using the npm.

So let’s type> npm install -g @angular/cli

Now let’s use some angular cli commands to initialize and create our angular app:

type> ng new tasks-app

It will ask you some questions, choose Yes and CSS

It would take some time to full create a new angular project, since it will be installing many angular-related and dependent packages through npm.

Once the blank app is created, make sure that Visual Studio code is navigating it, by choosing Open Folder and selecting the folder where you’ve just installed the new tasks-app

You should be getting the below:

That’s great, we have our initial empty angular app ready on the IDE, let’s use some more Angular CLI commands to generate the boilerplate components and services for us.

For this tutorial, we will need components for login, signup and home which will display the user’s tasks.

Also we will create some services that will be used as a middle layer between the components and the backend APIs, moreover, we will need some helpers to perform some useful actions in the code.

App Module

We need to import some libraries to use them within our tasks app. FormsModule will allow us to use the Angular Forms (Template or Reactive Forms) in our template files to build comprehensive forms with validations. And HttpClientModule is the library that facilitates the network communications with external APIs, which we will use to connect to our backend APIs.

Open App.Module.ts file and add the below import lines:

And in the Modules array, add the 2 modules there:

Now we have both libraries included in our project.

Requests and Responses

We will have 2 folders that will hold the requests and responses respectively. We will include Angular interfaces with properties structures similar to the ones we have on our API.

Doing such will make the communication between the Angular app and the API more convenient and consistent.

Requests

Now let’s generate an interface for LoginRequest under requests folder (the folder will be generated if it is not there):

LoginRequest

From the cmd, input the following command:

ng g interface requests/LoginRequest

SignupRequest

ng g interface requests/SignupRequest

RefreshTokenRequest

ng g interface requests/RefreshTokenRequest

TaskRequest

ng g interface requests/TaskRequest

At the end, you should see the following folder structure in your VS Code Explorer:

Next, is to create the responses interfaces which will bind to the API responses objects

Responses

TokenResponse

ng g interface responses/TokenResponse

TaskResponse

ng g interface responses/TaskResponse

ErrorResponse

This will hold the data whenever the API returns 422 Unprocessable Entity or 400 Bad Request Http Responses.

ng g interface responses/ErrorResponse

And this will be the content for the responses folder:

Now before we go to the service part, open the environment.ts file and include the apiUrl in the environment constant, like the below:

Services

This is layer where you include the calls to the backend APIs along with any other local services to the logic related to storing and retrieving data from session or local storage.

UserService

The user service includes the http calls to our backend users controller which has the endpoints including login, signup, logout, refreshToken and getUserInfo.

So, from the terminal, type: ng g s services/user

It will create for you services folder with a user-service.ts file.

Now, let take a look at the user service methods that we will add:

Notice how simple our methods are? The constructor injects the httpClient which will be used to do the http calls, and each method has this simple httpClient call, with providing the endpoint URL and the request object in case it was a non-get call.

We prefer to keep the services neat and clean without extra business logic, since these usually happen on the component ts file, once we subscribe to the returned Observable.

Moreover, you have to understand that these methods don’t do actions (http calls) once they are called, the actions happen once you call the subscribe method on them, only then the http call gets triggered and a response is returned either to the next part (success) or error part (fail), and the third section which is the complete part, it is triggered in both cases, this is where you can put finalizing logic such as stopping a progress bar from loading.

TokenService

The token service will handle the local validation, storage and retrieval of the tokens and key user details. This is a critical service to keep the angular app aware of the authentication related data.

so let’s create this service:

ng g s services/token

and here is the code:

TaskService

This service will hold the methods to call the tasks related endpoints.

from the terminal, type:

ng g s services/task

Some notes on the above code:

Even though these methods call endpoints that are authorized (must provide authorization header), we don’t pass the headers inside these methods, in the upcoming section we will see how we can apply the authorization header on each request in a single place, no need to repeat the process inside each method having an http call.

Interceptors

With interceptors, implementing the HttpInterceptor, you can inject some code into the http process pipeline to modify or process the outgoing/incoming http requests/responses.

2 important interceptors that you should add to your application would be the authorization interceptor for requests and the error interceptor for responses.

Authorization Interceptor

Using the terminal, add the below Angular CLI command to let it create the interceptor for you:

ng g interceptor interceptors/auth

Here is the code for the auth.interceptor:

See in the above code, we are checking if the user is logged in and the request is going to our backend APIs, not some other APIs, then we will add the Authorization header, with token type as bearer with the saved JWT token itself.

In case the user is not logged in or the API call is for a different API endpoint, then we just let the request continue its normal flow without any modification on it.

Error Interceptor

Let’s create another interceptor, this will intercept the response of the http call, log the responses and handle silently refreshing the access token if the API returned 401 unauthorized response. This interceptor will also propagate the error by a custom error class.

So let’s create the interceptor from the terminal:

ng g interceptor interceptors/error

And the code is below:

Then we need to include both interceptors within the app module file in the providers array, so let’s open app.module.ts

So it should look as the below:

Guard

The guard is a special class that can be used to make sure that a secured page is not accessible for any user who is not authenticated with a valid JWT token. This is the entry point to achieve this tutorial’s goal which is to Secure Angular Site using JWT Authentication.

So type the below command on the terminal:

ng g guard helpers\auth

and the guard code is here:

As you can see here, the guard is also checking if the token is expired and doing a silent refresh using the refresh token, in case the silent refresh failed, it means either the refresh token was revoked or got expired and therefore the user has to login again.

Components

These are your UI related building blocks that include both the template and the code behind it.

Tasks (Home)

ng g c tasks

task.component.html

task.component.ts

Login

Angular CLI Command: ng g c login

login.component.html

login.component.ts

Signup

Angular CLI Command: ng g c signup

signup.component.html

signup.component.ts

Profile

Angular CLI Command: ng g c profile

profile.component.html

profile.component.ts

App Component (Main)

This is the main layout for your site, where there is a navigation bar in the header part of the page and below it is the router-outlet which is the directive for the routing library that will toggle the display of the correct component based on the current url.

app.component.html

And here is the code behind of this main component that includes the title and isLoggedIn variables as well as the logout method which will clear the current tokens session from the local storage and navigate to the login screen.

app.component.ts

App Module

This is the final view of the app module class, with all the needed imports, declarations and providers.

app.module.ts

App Routing

In the app-routing we match the routes with the components, and also we can set some additional options like the canActivate to protect the component from being displayed in case of unauthorized access.

Testing our site

First let’s run the API project on localhost, you should get the below swagger screen on your browser:

Now let’s serve our Angular site on localhost port 4200

In the terminal, type this command: ng serve –open

this will build your angular site and serve it under localhost and open the default route on the browser:

Now let’s try to login without entering any value:

And let’s enter some valid credentials:

Now you should be logged in and redirected to the tasks route where you will be able to view, add, update and delete your tasks, also notice how the navigation bar has changed its links instead of sign up and login to profile and logout:

Now let’s add some tasks:

We just enter the task name, and press Add Task. You will see the task added to the list below with a date and remove button.

Let’s press on one of the tasks to mark it as completed:

Clicking on the first task, it got marked as completed and therefore its style has changed. Of course, when it comes to CSS and styling you have an open-ended possibilities of what you can achieve to perfect your design.

So let’s now remove a task:

That’s great. We have a functioning tasks management page here. Let’s open Profile to see how the profile will look like:

Of course you can continue this part by adding a proper form with fields and validation instead of just plain view of the data and allow the users to update their profile.

Now let’s logout from here:


The logout button redirected us to the login screen and cleared the previous session.

Let’s try to open the profile page to see if we can access it: http://localhost:4200/profile

You will be redirected to the login screen again, since it is guarded for only authorized access.

Now let’s see the signup screen:

Now let’s try to sign up without entering any field:

Now let’s enter some valid data:

The signup form will disappear and you will get a success message:

Now let’s try to login using the new email and password:

We will be redirected to the tasks screen with no tasks obviously.

And the profile will show the details for the new user:

To test the access token and refresh token, first you need to change the ExpiryDate property on the API project to relatively small numbers like 1 minute for the access token and 2 minutes for the refresh token, and see how the access token will be silently refreshed.

And if the refresh token is expired, you will notice the site will be automatically redirected to login screen.

Summary

In this tutorial we have learned how we can build and secure Angular site using JWT Authentication with Access Tokens and Refresh Tokens. We built components for login, signup, profile, tasks and a function to logout. we added services to connect to the backend APIs previously built with ASP.NET Core Web API which already has the JWT authentication implemented in it. We added a local service to manage storing and retrieving the tokens for the user on the site.

And finally we have run a quick test on the site to verify the behaviour of all the functions and actions.

References

The API project is hosted in GitHub and you can find the tutorial for it here: Apply JWT Access Tokens and Refresh Tokens in ASP.NET Core Web API 6

You can find the Angular project for this tutorial hosted in GitHub as well.

If you want to learn more about Angular, I would highly recommend you take the tour of heroes tutorial, it is the best way you can dig into the Angular world.

For ASP.NET Core Web API, you can check some of my other tutorials:

Bonus

I would dedicate this musical piece for my avid readers and selective music listeners, enjoy and be safe wherever you are!

Albinoni – Oboe Concerto #2 in D Minor Op. 9

5 Comments on “Secure Angular Site using JWT Authentication with ASP.NET Core Web API”

  1. incredibly front and back solution. I am going to rip out the kudzu kludge I have now and put in this clean and complete code. I always see it as a shame to see such stellar effort and sharing unacknowledged. Thanks!

  2. refreshToken(session: TokenResponse) {

    let refreshTokenRequest: any = {

    UserId: session.userId,

    RefreshToken: session.refreshToken

    }; why take in the TokenResponse while clearly it does not have a userId?

    1. Hello Ben, thanks for noticing this and sorry about this confusion, it was a mistake while preparing the snippets. It should be fixed now.
      Apologies for this again, have a great day.

Leave a Reply