Skip to main content

Part-1 | Angular(v14) JWT Access Token Authentication & Refresh Token

In this article, we are going to implement JWT(JSON Web Token) authentication in the Angular(v14) application. We also understand how to use the Refresh Token when the JWT Access Token expires.

JSON Web Token(JWT):

JSON Web Token is a digitally signed and secured token for user validation. The JWT is constructed with 3 informative parts:
  • Header
  • Payload
  • Signature

Create An Angular(v14) Application:

Let's create an Angular(v14) application to accomplish our demo.
Command To Create Angular App
ng new name_of_your_project

Let's install the bootstrap package
npm install bootstrap@5.2.0

Configure the bootstrap CSS and JS file reference in 'angular.json'.

Now let's add the bootstrap menu in 'app.component.html'.
src/app/app.component.html:
<nav class="navbar navbar-dark bg-primary">
  <div class="container-fluid">
    <a class="navbar-brand" routerLink="/">Jwt Auth Demo</a>
  </div>
</nav>
  • Here is the added home page route for the title of our application.

Create 'Home' Component:

Let's create an angular component like 'Home'. It will be like a home page that can be accessed by any kind of user, authentication is not required for this page.
ng generate component home --skip-tests

Now configure the 'Home' component route at 'AppRoutingModule'
src/app/app-routing.module.ts:
import { HomeComponent } from './home/home.component';
// existing code hidden for display purpose
const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
  },
];
Let's add the below HTML in 'home.component.html' to display a simple welcome message.
src/app/home/home.component.html: 
<div class="container">
  <div class="row mt-5">
    <div class="col d-flex justify-content-center">
      <div class="card">
        <div class="card-body">
          <h1 class="card-title d-flex justify-content-center">Welcome!</h1>
          <h4 class="card-title">Angular 14 JWT authentication.</h4>
        </div>
      </div>
    </div>
  </div>
</div>

API For Authentication:

Now we need an authentication API for generating the jwt token or refreshing token. To achieve the JWT authentication, I have created a sample application using NestJS(nodejs). So what to install, how to set up, how to run the API, test credentials everything in detail explained in the below GitHub link so please check them after cloning the application.

Create A 'Auth' Feature Module And 'Login' Component:

Let's create a feature module like the 'Auth' module.
ng generate module auth --routing

Let's do a lazy loading module route configuration at 'app-routing.module.ts'.
src/app/app-routing.module.ts:
// existing code hidden for display purpose
const routes: Routes = [
  {
    path: 'auth',
    loadChildren: () => import('./auth/auth.module').then((_) => _.AuthModule),
  },
];
Let's create the 'Login' component inside of the 'Auth' module.
ng generate component auth/login --skip-tests

Let's add the 'Login' component route inside of the 'auth-routing.module.ts'.
src/app/auth/auth-routing.module.ts:
import { LoginComponent } from './login/login.component';

const routes: Routes = [{
  path:'login',
  component: LoginComponent
}];

Install @auth0/angular-jwt Package:

The benefits of  using the '@auth0/angular-jwt' package are:
  • Easy to decrypt the JWT token to read the payload inside of the token
  • Easy to determine token expiration
  • Automatically adds the 'authorization' header and token as value to API request
  • Easy to maintain the authentication state.
npm install @auth0/angular-jwt

Implement Login API Call:

Let's first create the login API payload model like 'LoginModel'.
ng generate interface auth/login-model
src/app/auth/login-model.ts:
export interface LoginModel {
  username: string;
  password: string;
}
  • Here 'username', 'password', properties please make sure to copy those property names from the GitHub Link.
Let's create the response model for login API like 'TokenModel', but the 'TokenModel' has to be available to the entire application so we need to create it under the 'shared/auth' folders(new folders).
ng generate interface shared/auth/token-model
src/app/shared/auth/token-model.ts:
export interface TokenModel {
  access_token: string;
  refresh_token: string;
}
The JWT token contains some user claims like 'email', 'username', 'exp', etc. So we can use this information to display on our angular application. So we will decode the jwt token and we will create the model for this data like 'UserProfile'.

ng generate interface shared/auth/user-profile
src/app/shared/auth/user-profile.ts:
export interface UserProfile {
  username: string;
  sub: number;
  email: string;
  iat: number;
  exp: number;
}
Create a service like 'AuthService' which contains API call logic. The 'AuthService' add under the 'shared/auth' folder.
ng generate service shared/auth/auth --skip-tests
src/app/shared/auth/auth.service.ts:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { JwtHelperService } from '@auth0/angular-jwt';
import { BehaviorSubject, catchError, map, of } from 'rxjs';
import { LoginModel } from 'src/app/auth/login-model';
import { TokenModel } from './token-model';
import { UserProfile } from './user-profile';

@Injectable({
  providedIn: 'root',
})
export class AuthService {
  constructor(private httpClient: HttpClient) {}
  userProfile = new BehaviorSubject<UserProfile | null>(null);
  jwtService: JwtHelperService = new JwtHelperService();

  userLogin(payload: LoginModel) {
    return this.httpClient
      .post('http://localhost:3000/auth/login', payload)
      .pipe(
        map((data) => {
          var token = data as TokenModel;

          localStorage.setItem('tokens', JSON.stringify(token));

          var userInfo = this.jwtService.decodeToken(
            token.access_token
          ) as UserProfile;

          this.userProfile.next(userInfo);

          return true;
        }),
        catchError((error) => {
          console.log(error);
          return of(false);
        })
    );
  }
}
  • (Line: 12) Inject the 'HttpClient' loads from the '@angular/common/http'.
  • (Line: 13) Declared a 'userProfile' variable of type BehaviorSubject<UserProfile>.
  • (Line: 14) Declare a 'jwtService' variable of type 'JwtHelperService' that loads from the '@auth0/angular-jwt'.
  • (Line: 16-39)  The 'userLogin()' method invokes login API.
  • (Line: 19) Added the login API and user credentials as payload.
  • (Line: 22) API response type cast to 'TokenModel'.
  • (Line: 24) Convert the 'TokenModel' to string and then save to browser local storage.
  • (Line: 26-28) Using 'JwtHelperService' decode the jwt access token and then type cast as 'UserProfile'.
  • (Line: 30) Update the 'userProfile' observable variable.
Add the 'HttpClientModule' in 'AppModule'.
src/app/app.module.ts:
import { HttpClientModule } from '@angular/common/http';
// code hidden for display purpose
@NgModule({
  imports: [
    HttpClientModule
  ]
})
export class AppModule { }

Login Form:

Let's update the 'login.component.ts' as below.
src/app/auth/login/login.component.ts:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from 'src/app/shared/auth/auth.service';
import { LoginModel } from '../login-model';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css'],
})
export class LoginComponent implements OnInit {
  constructor(private authService: AuthService, private router: Router) {}

  loginForm: LoginModel = {
    username: '',
    password: '',
  };

  ngOnInit(): void {}

  userLogin() {
    this.authService.userLogin(this.loginForm).subscribe((data) => {
      if (data) {
        this.router.navigate(['/']);
      }
    });
  }
}
  • (Line: 12) Injected the 'AuthService' and the 'Router' services.
  • (Line: 14-17) Declared and initialized the 'loginForm' of type 'LoginModel'.
  • (Line: 21-27) The 'userLogin()' method invokes the login API call. On login, success navigates back to the home page.
src/app/auth/login/login.component.html:
<div class="container">
    <legend>Sign-In</legend>
    <div class="mb-3">
      <label for="txtUserName" class="form-label">User Name</label>
      <input
        type="text"
        class="form-control"
        id="txtUserName"
        [(ngModel)]="loginForm.username"
      />
    </div>
    <div class="mb-3">
      <label for="txtPassword" class="form-label">Password</label>
      <input
        type="password"
        class="form-control"
        id="txtPassword"
        [(ngModel)]="loginForm.password"
      />
    </div>
    <button class="btn btn-primary" (click)="userLogin()">Login</button>
</div>
  • Here simple form with 'username' and 'password' fields and the button to submit the form whose click event registered to 'userLogin()' method.
Add the 'FormsModule' into the 'AuthModule'.
src/app/auth/auth.module.ts:
import { FormsModule } from '@angular/forms';
// existing code hidden for display purpose
@NgModule({
  imports: [
    FormsModule
  ]
})
export class AuthModule { }
Now let's try to read the authenticated information into the 'App' component that is because we need to toggle the login menu item and also we need to bind the user email to the menu if the user logged in successfully.
src/app/app.component.ts:
import { Component, OnInit } from '@angular/core';
import { AuthService } from './shared/auth/auth.service';
import { UserProfile } from './shared/auth/user-profile';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  constructor(private authService: AuthService) {}
  title = 'ang14-jwtauth';
  userProfile?: UserProfile | null;

  ngOnInit(): void {
    this.authService.userProfile.subscribe((data) => {
      this.userProfile = data;
    });
  }
}
  • (Line: 13) Declared the 'userProfile' variable.
  • (Line: 16-18) Listening for the data from the 'authService.userProfile' behavior subject.
src/app/app.component.html:
<nav class="navbar navbar-dark bg-primary">
  <div class="container-fluid">
    <a class="navbar-brand" routerLink="/">Jwt Auth Demo</a>
    <div class="d-flex">
      <ul class="navbar-nav">
        <li class="nav-item" *ngIf="(userProfile?.sub ?? 0) == 0">
          <a class="nav-link active"  routerLink="/auth/login">Login</a>
        </li>
        <li class="nav-item" *ngIf="(userProfile?.sub ?? 0) > 0">
          <a class="nav-link active"  href="#">{{userProfile?.email}}</a>
        </li>
      </ul>
    </div>
  </div>
</nav>
  • Here 'sub' is the user id value. If the sub value is 0 then use not authenticated then we show 'Login' menu item. If the sub value is greater than 0 then the user is authenticated then we hide the 'Login' menu and display user's email as one of the menu items.
(Step 1)

(Step 2)

(Step 3)

(Step 4)

Create A 'Movies' Feature Module And 'Fav-Movie' Component:

Till now we have completed the user authentication by fetching the JWT access token. Now let's try to consume a secure endpoint that requires jwt access token authorization header value. So to accomplish this let's create new 'Movies' Feature Module and a 'Fav-Movie' component.

Let's create our feature module
ng generate module movies --routing

Now let's implement the 'Movies' module lazy load route at 'AppRoutingModule'.
src/app/app-routing.module.ts:
// hidden existing code for display purpose
const routes: Routes = [
  {
    path: 'movies',
    loadChildren: () =>
      import('./movies/movies.module').then((_) => _.MoviesModule),
  },
]
Let's create the 'Fav-Movie' component inside of the  'Movies' module.
ng generate component movies/fav-movie --skip-tests
Now configure 'Fav-Movie' component routing in 'MoviesRoutingModule'.
src/app/movies/movies-routing.module.ts:
import { FavMovieComponent } from './fav-movie/fav-movie.component';
// existing code hidden for dispal
const routes: Routes = [
  {
    path: 'fav-movies',
    component: FavMovieComponent,
  },
];

Implement Logic To Consume Secure Endpoint:

The  secured endpoint and its response can be looked at NestJS Github Link

Let's create an API response model like 'fav-movie.ts'.
ng generate interface movies/fav-movie
src/app/movies/fav-movie.ts:
export interface FavMovie {
  id: number;
  name: string;
  genre: string;
}
Let's create a  service file like 'movies.service.ts'.
ng generate service movies/movies --skip-tests
src/app/movies/movies.service.ts:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FavMovie } from './fav-movie';

@Injectable({
  providedIn: 'root',
})
export class MoviesService {
  constructor(private httpClient: HttpClient) {}

  getFavMovies() {
    return this.httpClient.get<FavMovie[]>('http://localhost:3000/user/fav-movies');
  }
}
  • (Line: 11-13) Secured API call.
Let's at the following logic into the 'fav-movie.component.ts'.
src/app/movies/fav-movie/fav-movie.component.ts:
import { Component, OnInit } from '@angular/core';
import { FavMovie } from '../fav-movie';
import { MoviesService } from '../movies.service';

@Component({
  selector: 'app-fav-movie',
  templateUrl: './fav-movie.component.html',
  styleUrls: ['./fav-movie.component.css']
})
export class FavMovieComponent implements OnInit {

  constructor(private moviesService:MoviesService) { }

  faveMovies:FavMovie[] = [];

  ngOnInit(): void {
    this.moviesService.getFavMovies()
    .subscribe((data) => {
      this.faveMovies = data;
    })
  }

}
  • (Line: 14) Declared the 'favMovies' variable of an array of types 'FavMovies'.
  • (Line: 17-19) Invoking the secured API endpoint.
src/app/movies/fav-movies/fav-movies.component.html:
<div class="row row-cols-1 row-cols-md-2 g-4">
  <div class="col" *ngFor="let fav of faveMovies">
    <div class="card">
      <div class="card-body">
        <h5 class="card-title">{{ fav.name }}</h5>
        <p class="card-text">Genere | {{ fav.genre }}</p>
      </div>
    </div>
  </div>
</div>
Let's add the new menu item for the movies.
src/app/app.component.html:
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
  <div class="container-fluid">
    <a class="navbar-brand" routerLink="/">Jwt Auth Demo</a>
    <div class="collapse navbar-collapse">
      <ul class="navbar-nav">
        <li class="nav-item" *ngIf="(userProfile?.sub ?? 0) > 0">
          <a class="nav-link active" routerLink="/movies/fav-movies">Movies</a>
        </li>
      </ul>
    </div>
    <div class="d-flex">
      <ul class="navbar-nav">
        <li class="nav-item" *ngIf="(userProfile?.sub ?? 0) == 0">
          <a class="nav-link active" routerLink="/auth/login">Login</a>
        </li>
        <li class="nav-item" *ngIf="(userProfile?.sub ?? 0) > 0">
          <a class="nav-link active" href="#">{{ userProfile?.email }}</a>
        </li>
      </ul>
    </div>
  </div>
</nav>
<router-outlet></router-outlet>
  • (Line: 6-8) Add the 'Movies' menu item.
Now run the application and then navigate to the 'Movies' page then you can see our secure API fails as below because of jwt token was not added as an authorization header value.

Configure JWT Module From '@auth0/angular-jwt':

The '@auth0/angular-jwt' library support automatically adding the jwt access token as an authorization header value to the API calls.

In 'AuthService' let's create a method that always tries to read the token from the browser's local storage.
src/app/shared/auth/auth.service.ts:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { JwtHelperService } from '@auth0/angular-jwt';
import { BehaviorSubject, catchError, map, of } from 'rxjs';
import { LoginModel } from 'src/app/auth/login-model';
import { TokenModel } from './token-model';
import { UserProfile } from './user-profile';

// existing code hidden for display purpose

@Injectable({
  providedIn: 'root',
})
export class AuthService {
  constructor(private httpClient: HttpClient) {}
  userProfile = new BehaviorSubject<UserProfile | null>(null);
  jwtService: JwtHelperService = new JwtHelperService();

  getAccessToken():string{
    var localStorageToken = localStorage.getItem('tokens');
    if(localStorageToken){
      var token = JSON.parse(localStorageToken) as TokenModel;
      var isTokenExpired = this.jwtService.isTokenExpired(token.access_token);
      if(isTokenExpired){
        this.userProfile.next(null);
        return "";
      }
      var userInfo = this.jwtService.decodeToken(
        token.access_token
      ) as UserProfile;
      this.userProfile.next(userInfo);
      return token.access_token;
    }
    return "";
  }
}
  • (Line: 19-35) The 'getAccessToken()' method is used by the JWTModule for fetching the access token from the browser's local storage.
  • (Line: 20) Fetching token data from the browser's local storage.
  • (Line: 21-27) The logic is executed if the tokens exist in the browser's local storage.
  • (Line: 23) Checked jwt access token expired or not.
  • (Line: 24-27) If the token expired then pass 'null' data to the 'userProfile' observable and then return the empty string value.
  • (Line: 28-32) If the token is not expired then decode the jwt access token and then pass data to the 'userProfile' observable and finally return the access token
Let's configure the JwtModule in  'AppModule'.
src/app/app.module.ts:
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { JwtModule, JWT_OPTIONS } from '@auth0/angular-jwt';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { AuthService } from './shared/auth/auth.service';

export function jwtOptionFactor(authService:AuthService){
  return {
    tokenGetter:() => {
      return authService.getAccessToken();
    },
    allowedDomains:["localhost:3000"],
    disallowedRoutes:[
      "http://localhost:3000/auth/login"
    ]
  }
}

// existing code hidden for display purpose
@NgModule({
  
  imports: [
    JwtModule.forRoot({
      jwtOptionsProvider:{
        provide:JWT_OPTIONS,
        useFactory: jwtOptionFactor,
        deps:[AuthService]
      } 
    })
  ]
})
export class AppModule { }
  • (Line: 11-21) The 'jwtOptionFactor' is the factory method for loading the setting of the jwt token into the 'JwtModule'. Here this method takes 'AuthService' as an input parameter.
  • (Line: 13-15) The 'tokenGetter' always watches for the jwt token.
  • (Line: 16) The 'allowedDomains' is the area to register the domains to which jwt token authorization header value to be added automatically.
  • (Line: 17-19) The 'disallowedRoutes' to specify the routes which don't need a jwt token as authorization header for example login API never requires the jwt token.
  • (Line: 27-33) Imported the 'JwtModule' that loads from the '@auth0/angular-jwt'.
  • (Line: 30) To the 'useFactory' property assign our 'jwtOptionFactor' function.
  • (Line: 31) The 'deps' represent dependencies here we have to pass our 'AuthService' that is because we are using the 'AuthService' as an input parameter to 'jwtOptionFactor' function.
Now run the application and then log-in and then go to the 'Movies' page then we can observe we able to access the secured API endpoint
(Step 1)

(Step 2)

In the next part of the article, we will implement angular routing guards, interceptors to invoke the refresh token endpoint, and then finally user logout.

Support Me!
Buy Me A Coffee PayPal Me

Video Session:

Wrapping Up:

Hopefully, I think this article delivered some useful information on the Angular 14 Jwt Access Token Authentication and Refresh Token. using I love to have your feedback, suggestions, and better techniques in the comment section below.

Refer:

Follow Me:

Comments

Popular posts from this blog

.NET6 Web API CRUD Operation With Entity Framework Core

In this article, we are going to do a small demo on AspNetCore 6 Web API CRUD operations. What Is Web API: Web API is a framework for building HTTP services that can be accessed from any client like browser, mobile devices, desktop apps. In simple terminology API(Application Programming Interface) means an interface module that contains a programming function that can be requested via HTTP calls to save or fetch the data for their respective clients. Some of the key characteristics of API: Supports HTTP verbs like 'GET', 'POST', 'PUT', 'DELETE', etc. Supports default responses like 'XML' and 'JSON'. Also can define custom responses. Supports self-hosting or individual hosting, so that all different kinds of apps can consume it. Authentication and Authorization are easy to implement. The ideal platform to build REST full services. Create A .NET6 Web API Application: Let's create a .Net6 Web API sample application to accomplish our

Angular 14 Reactive Forms Example

In this article, we will explore the Angular(14) reactive forms with an example. Reactive Forms: Angular reactive forms support model-driven techniques to handle the form's input values. The reactive forms state is immutable, any form filed change creates a new state for the form. Reactive forms are built around observable streams, where form inputs and values are provided as streams of input values, which can be accessed synchronously. Some key notations that involve in reactive forms are like: FormControl - each input element in the form is 'FormControl'. The 'FormControl' tracks the value and validation status of form fields. FormGroup - Track the value and validate the state of the group of 'FormControl'. FormBuilder - Angular service which can be used to create the 'FormGroup' or FormControl instance quickly. Form Array - That can hold infinite form control, this helps to create dynamic forms. Create An Angular(14) Application: Let'

Part-1 Angular JWT Authentication Using HTTP Only Cookie[Angular V13]

In this article, we are going to implement a sample angular application authentication using HTTP only cookie that contains a JWT token. HTTP Only JWT Cookie: In a SPA(Single Page Application) Authentication JWT token either can be stored in browser 'LocalStorage' or in 'Cookie'. Storing JWT token inside of the cookie then the cookie should be HTTP Only. The HTTP-Only cookie nature is that it will be only accessible by the server application. Client apps like javascript-based apps can't access the HTTP-Only cookie. So if we use authentication with HTTP only JWT cookie then we no need to implement custom logic like adding authorization header or storing token data, etc at our client application. Because once the user authenticated cookie will be automatically sent to the server by the browser on every API call. Authentication API: To implement JWT cookie authentication we need to set up an API. For that, I had created a mock authentication API(Using the NestJS Se

Unit Testing Asp.NetCore Web API Using xUnit[.NET6]

In this article, we are going to write test cases to an Asp.NetCore Web API(.NET6) application using the xUnit. xUnit For .NET: The xUnit for .Net is a free, open-source, community-focused unit testing tool for .NET applications. By default .Net also provides a xUnit project template to implement test cases. Unit test cases build upon the 'AAA' formula that means 'Arrange', 'Act' and 'Assert' Arrange - Declaring variables, objects, instantiating mocks, etc. Act - Calling or invoking the method that needs to be tested. Assert - The assert ensures that code behaves as expected means yielding expected output. Create An API And Unit Test Projects: Let's create a .Net6 Web API and xUnit sample applications to accomplish our demo. We can use either Visual Studio 2022 or Visual Studio Code(using .NET CLI commands) to create any.Net6 application. For this demo, I'm using the 'Visual Studio Code'(using the .NET CLI command) editor. Create a fo

A Small Guide On NestJS Queues

NestJS Application Queues helps to deal with application scaling and performance challenges. When To Use Queues?: API request that mostly involves in time taking operations like CPU bound operation, doing them synchronously which will result in thread blocking. So to avoid these issues, it is an appropriate way to make the CPU-bound operation separate background job.  In nestjs one of the best solutions for these kinds of tasks is to implement the Queues. For queueing mechanism in the nestjs application most recommended library is '@nestjs/bull'(Bull is nodejs queue library). The 'Bull' depends on Redis cache for data storage like a job. So in this queueing technique, we will create services like 'Producer' and 'Consumer'. The 'Producer' is used to push our jobs into the Redis stores. The consumer will read those jobs(eg: CPU Bound Operations) and process them. So by using this queues technique user requests processed very fastly because actually

Angular 14 State Management CRUD Example With NgRx(14)

In this article, we are going to implement the Angular(14) state management CRUD example with NgRx(14) NgRx Store For State Management: In an angular application to share consistent data between multiple components, we use NgRx state management. Using NgRx state helps to avoid unwanted API calls, easy to maintain consistent data, etc. The main building blocks for the NgRx store are: Actions - NgRx actions represents event to trigger the reducers to save the data into the stores. Reducer - Reducer's pure function, which is used to create a new state on data change. Store - The store is the model or entity that holds the data. Selector - Selector to fetch the slices of data from the store to angular components. Effects - Effects deals with external network calls like API. The effect gets executed based the action performed Ngrx State Management flow: The angular component needs data for binding.  So angular component calls an action that is responsible for invoking the API call.  Aft

Usage Of CancellationToken In Asp.Net Core Applications

When To Use CancellationToken?: In a web application request abortion or orphan, requests are quite common. On users disconnected by network interruption or navigating between multiple pages before proper response or closing of the browser, tabs make the request aborted or orphan. An orphan request can't deliver a response to the client, but it will execute all steps(like database calls, HTTP calls, etc) at the server. Complete execution of an orphan request at the server might not be a problem generally if at all requests need to work on time taking a job at the server in those cases might be nice to terminate the execution immediately. So CancellationToken can be used to terminate a request execution at the server immediately once the request is aborted or orphan. Here we are going to see some sample code snippets about implementing a CancellationToken for Entity FrameworkCore, Dapper ORM, and HttpClient calls in Asp.NetCore MVC application. Note: The sample codes I will show in

Blazor WebAssembly Custom Authentication From Scratch

In this article, we are going to explore and implement custom authentication from the scratch. In this sample, we will use JWT authentication for user authentication. Main Building Blocks Of Blazor WebAssembly Authentication: The core concepts of blazor webassembly authentication are: AuthenticationStateProvider Service AuthorizeView Component Task<AuthenticationState> Cascading Property CascadingAuthenticationState Component AuthorizeRouteView Component AuthenticationStateProvider Service - this provider holds the authentication information about the login user. The 'GetAuthenticationStateAsync()' method in the Authentication state provider returns user AuthenticationState. The 'NotifyAuthenticationStateChaged()' to notify the latest user information within the components which using this AuthenticationStateProvider. AuthorizeView Component - displays different content depending on the user authorization state. This component uses the AuthenticationStateProvider

How Response Caching Works In Asp.Net Core

What Is Response Caching?: Response Caching means storing of response output and using stored response until it's under it's the expiration time. Response Caching approach cuts down some requests to the server and also reduces some workload on the server. Response Caching Headers: Response Caching carried out by the few Http based headers information between client and server. Main Response Caching Headers are like below Cache-Control Pragma Vary Cache-Control Header: Cache-Control header is the main header type for the response caching. Cache-Control will be decorated with the following directives. public - this directive indicates any cache may store the response. private - this directive allows to store response with respect to a single user and can't be stored with shared cache stores. max-age - this directive represents a time to hold a response in the cache. no-cache - this directive represents no storing of response and always fetch the fr

Angular 14 Crud Example

In this article, we will implement CRUD operation in the Angular 14 application. Angular: Angular is a framework that can be used to build a single-page application. Angular applications are built with components that make our code simple and clean. Angular components compose of 3 files like TypeScript File(*.ts), Html File(*.html), CSS File(*.cs) Components typescript file and HTML file support 2-way binding which means data flow is bi-directional Component typescript file listens for all HTML events from the HTML file. Create Angular(14) Application: Let's create an Angular(14) application to begin our sample. Make sure to install the Angular CLI tool into our local machine because it provides easy CLI commands to play with the angular application. Command To Install Angular CLI npm install -g @angular/cli Run the below command to create the angular application. Command To Create Angular Application ng new name_of_your_app Note: While creating the app, you will see a noti