How to implement JWT Token Authentication in Angular with .NET Core?

In this article, we will demonstrate JWT Token Authentication in Angular with .NET Core.

To implement the JWT Token authentication mechanism, we will use the –

What is a JWT Token?

JWT stands for JSON Web Tokens. It is a Token-based authentication to communicate with the REST endpoints securely. It is a JSON-based token so you can store a good amount of data within it.

How does JWT Token Authentication work?

You can understand the JWT Token Authentication process in the below steps.

  • Provide Login credentials (User Name and Password) to authenticate for the first time.
  • The server receives the credentials and checks the information in the data source.
  • On successful authentication, with the help of JWT libraries, the server creates a JSON-based Web Token.
  • For the subsequent communication with the server, the client sends that token instead of the User Name and Password. The client adds a JWT token in the Header. The syntax is Bearer<space><JWT Token>
  • The server receives the JWT Token and validates the same before allowing the user to further actions.
  • JWT Token has an expiry time. After logging out, the JWT token gets flushed.

How to implement JWT Token Authentication in Angular with .NET Core?

Let’s demonstrate JWT Token Authentication in Angular with .NET Core step by step.

Read Full Article to know how to generate JWT Token in .NET Core

JWT Token Authentication Example with .NET 5 – SharePointCafe.Net

Create a .NET Core application

Create a .NET Core-based Web API in Visual Studio.

Add an Interface IJWTTokenAuth

public interface IJWTTokenAuth
    {
        string Authenticate(string username, string password);
    }

Add a class and implement the interface. Change the App URL in the below code snippet.

public class JWTToeknAuth : IJWTTokenAuth
    {
        private readonly string key;
        public JWTToeknAuth(string key)
        {
            this.key = key;
        }
        public string Authenticate(string username, string password)
        {
            if (username == "test" && password == "12345")
            {
                string issuer = "App URL";
                string audience = "App URL";
                var tokenKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("MyConfidentialKey"));
                var signingCredentials = new SigningCredentials(tokenKey, SecurityAlgorithms.HmacSha256);
                var token = new JwtSecurityToken(issuer, audience, expires: DateTime.Now.AddMinutes(1), signingCredentials: signingCredentials);
                return new JwtSecurityTokenHandler().WriteToken(token);
            }

            else
                return null;
        }
    }

Add below code snippet inside the ConfigureService() method available under Startup.cs file. Change the App URL in the below code snippet.

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(x =>
            {
                var serverSecret = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("MyConfidentialKey"));
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    IssuerSigningKey = serverSecret,
                    ValidIssuer = "App URL",
                    ValidAudience = "App URL"
                };
            });
 services.AddSingleton<IJWTTokenAuth>(new JWTToeknAuth("MyConfidentialKey"));

Create a controller class and add the below action method –

 private readonly IJWTTokenAuth jWTTokenAuth;
 public WeatherForecastController(ILogger<WeatherForecastController> logger, IJWTTokenAuth jWTTokenAuth)
        {
            _logger = logger;
            this.jWTTokenAuth = jWTTokenAuth;
        }       

        [AllowAnonymous]
        [HttpPost("jwtauth")]
        public IActionResult Authenticate([FromBody] Users usrs)
        {
            var jwtToken = jWTTokenAuth.Authenticate(usrs.UserName, usrs.Password);
            if (jwtToken == null)
                return Unauthorized();
            else
                return Ok(new {Token = jwtToken });
        }

We will use the below action method to get data for Authenticated users.

       [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }

Add Authorize attribute to the controller class.

[Authorize]

Change the Route attribute

 [Route("api/[controller]")]

Declare a variable of type IJWTTokenAuth

private readonly IJWTTokenAuth jWTTokenAuth;

Add a parameter to the constructor of type IJWTTokenAuth

public WeatherForecastController(ILogger<WeatherForecastController> logger, IJWTTokenAuth jWTTokenAuth)
        {
            _logger = logger;
            this.jWTTokenAuth = jWTTokenAuth;
        }

Make sure to add the below lines in Configure() method of Startup.cs file

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

Allow CORS as per your requirements. To demonstrate this article, I have allowed all methods and all origins.

Add below code snippet in Configure() method of Startup.cs file.

 app.UseCors(x => x
                .AllowAnyMethod()
                .AllowAnyHeader()
                .SetIsOriginAllowed(origin => true)  
                .AllowCredentials()); 

Create Angular application

Next, We will create a new angular project. Use the below command to create a new Angular project.

ng new pilot-project

Add a service file using the below command.

ng g service api-service

Below is the complete code of the service file in Angular.

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ApiServiceService {
  url = 'http://localhost:61187/api/';
  auth_token : any
  response: any
  constructor(private http: HttpClient) { }

  postData(userData:User) {
    const httpHeaders = { headers:new HttpHeaders({'Content-Type': 'application/json'}) };
    this.response = this.http.post<String>(this.url + 'WeatherForecast/jwtauth', userData, httpHeaders);
    return this.response;
     
  }

  getWeatherData() {
    this.auth_token = localStorage.getItem("jwt");
    const headerDict = {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Access-Control-Allow-Headers': 'Content-Type',
      'Authorization': 'Bearer ' + this.auth_token
    }
    const httpHeaders = { headers:new HttpHeaders(headerDict)};
    return this.http.get(this.url + 'WeatherForecast',  httpHeaders);
  }
}

export class User {
 UserName:string
 Password: string;
}

Make Sure you import modules in the app.module.ts file

 imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule
  ]

Add a component file.

ng generate component api-calling

Below is the complete code snippet of the Component File

<h1>This is a JWT Auth Token Demo</h1>
<div class="container-fluid">
    <h2>Login to Proceed</h2>
<form [formGroup]="userForm">

    <div class="form-outline mb-4">
        <input type="text" class="form-control" id="UserName" formControlName="UserName" placeholder="User Name">
    </div>

    <div class="form-outline mb-4">
        <input type="password" class="form-control" id="Password" formControlName="Password" placeholder="Password">
      </div>
    <button type="submit" class="btn btn-primary" (click)="PostData(userForm.value)">Login</button> 
</form>
</div>
<hr>
<div>
    <button type="submit" class="btn btn-primary" (click)="GetWeatherData()">Show Weather Details</button> 
</div>
<table *ngIf="isValidUser" class="table">
    <thead>
        <tr>
            <th scope="col">Date</th>
            <th scope="col">Temprature in (C)</th>
            <th scope="col">Temprature in (F)</th>
            <th scope="col">Summary</th>
        </tr>
    </thead>
  <tbody>
    <tr *ngFor="let data of res">
        <td>
            {{data.date}}
        </td>
        <td>
            {{data.temperatureC}}
        </td>
        <td>
            {{data.temperatureF}}
        </td>
        <td>
            {{data.summary}}
        </td>
    </tr>
  </tbody>
</table>
<div style="color: red;">
    {{massage }}
</div>

Below is the complete code snippet of the Component ts file.

import { Component } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { FormBuilder, Validators } from '@angular/forms';
import { ApiServiceService, User } from '../api-service.service';
import { Table } from 'primeng/table';
import { NgbModal, NgbModule } from '@ng-bootstrap/ng-bootstrap';
 

@Component({
  selector: 'app-api-calling',
  templateUrl: './api-calling.component.html',
  styleUrls: ['./api-calling.component.css']
})
export class ApiCallingComponent {
  userForm: any;
  massage: any;
  userData: any;
  res: any;
  resstatus: any;
  isValidUser: boolean = false;



  constructor(private formbulider: FormBuilder, private httpClient: HttpClient, private userService: ApiServiceService,
    private modalService: NgbModal) { }

  ngOnInit(): void {
    this.userForm = this.formbulider.group({
      UserName: ['', [Validators.required]],
      Password: ['', [Validators.required]]
    });
  }

  PostData(user: User) {
    
    const user_Master = this.userForm.value;
    this.userData = JSON.stringify(user_Master);
    this.userService.postData(user_Master).subscribe
      ((response: any) => {
        const token = (<any>response).token
        localStorage.setItem("jwt", token);
        this.massage = 'You are now authorize';
        this.isValidUser = true;
         
      }
    );
  }

  GetWeatherData() {
    
    const product_Master = this.userForm.value;
    this.userService.getWeatherData().subscribe(
      (response: any) => {
        this.res = (<any>response)
         console.log(this.res);
         this.resstatus = "OK";
         this.isValidUser = true;
         
      }, (error) => {
        this.resstatus = error.status;
        if(this.resstatus == 401)
        {
          this.massage = "You are not authorize to view the data. Please login and try again.";
          this.isValidUser = false;
        }
        this.res = "";
    }
      
    );
  }
}

Add route path

const routes: Routes = [
{path:'apiauthtest', component:ApiCallingComponent}
];

Note: I have added Bootstrap for this demonstration. This is totally optional. If you wish to use the bootstrap for your project then you can install it using the below command.

npm install bootstrap

Next, add the below line in the index.html file

<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.css">

Output

JWT Token with .NET Core and Angular

If a user is not logged in and clicks on Show Weather Details then it will return a 401 status code and will show “You are not authorised to view the data. Please log in and try again.

JWT Token demo with .NET core and Angular

Post login, the user can view the data by clicking on the Show Weather Details button. This will validate the user on basis of the JWT token received after successful login.

JWT Token Authentication in Angular with .NET Core
JWT Token Authentication in Angular with .NET Core

Conclusion

So, in this article, we learnt about JWT Tone and then created a basic .NET Core project and an Angular project to authenticate using the JWT token.

Hope, this article is useful to you. Please share your feedback in below comment box below.

Leave a Comment

RSS
YouTube
YouTube
Instagram