Garry Taylor

Garry Taylor

1558344116

Angular JWT Authorization

Securing a Single Page Application is a very important part of its implementation, yet sometimes it brings a lot of confusion, especially when there are many ways to achieve it. In this article, I will focus on the approach utilizing JSON Web Tokens (JWT) as a mechanism to convey user rights. Moreover, I will present the benefits and potential pitfalls of JWT-based security.

In this article, you will learn:

  • how to restrict access to the given parts of Angular application, using Router Guards
  • how to intercept HTTP calls, adding an Access Token as it is required by the server
  • why we need a Refresh Token and how to use it transparently for the user

Table of contents

  • Application setup
  • Router Guards
  • JSON Web Token
  • Http interceptor
  • Refresh Token
  • AuthService
  • Summary

Application setup

Let’s think of the common use case where there are some pages (routes) in the application that the access to is restricted only for authorized users. After successful authentication, for example via a login form, the user is granted with an access to some restricted parts of the system (for example an admin page).

Authentication is the process of proving one’s identity. If we talk about login form, we assume that if a person is in the possession of the password associated with the given username, then that must be the person that this username belongs to.> Authorization happens after successful authentication and determines if the given user is authorized to access given resources (for example subpages in SPA).
For the sake of simplicity let’s assume that we have an application with a login page, available under /login route, and a page displaying a random number generated by the server, available under /secret-random-number. The random number page should be available only for the authorized users. If we manually try to access /secret-random-number we should be redirected back to the login page.

Router Guards

To achieve the goal of restricting access to /secret-random-number and redirecting back to the login page, in case the user is not logged in, we can make use of Angular’s built-in mechanism called Router Guards. These guards allow us to implement policies governing possible route transitions in an Angular application. Imagine a situation when a user tries to open a page that he has no access rights to. In such a case application should not allow this route transition. To achieve this goal we can make use of CanActivate guard. As Router Guards are just simple class providers, we need to implement a proper interface. Let’s take a look at below code snippet presenting AuthGuard.

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  constructor(private authService: AuthService, private router: Router) { }

  canActivate() {
    if (this.authService.isLoggedIn()) {
      this.router.navigate(['/secret-random-number']);
    }
    return !this.authService.isLoggedIn();
  }
}

AuthGuard implements canActivate() which tells Angular router whether it can or cannot activate a particular route. To attach given guard to the route that it should protect, we just need to place its reference in canActivate property of that route as presented below. In our case, we want to protect the /login route. We want to allow users to open this route, only if they are not logged in. Otherwise, we redirect to /secret-random-number. The same approach applies to protecting other routes, with different policies implemented for given routes. Also, we can notice the canLoad property in below routes configuration. This kind of protection allows us to prevent a lazy-loaded route from being fetched from the server. Usually, canLoad guards implement the same policy as canActivate guards.

const routes: Routes = [
  { path: '', pathMatch: 'full', redirectTo: '/login' },
  {
    path: 'login',
    component: LoginComponent,
    canActivate: [AuthGuard]
  },
  {
    path: 'secret-random-number',
    loadChildren: './random/random.module#RandomModule',
    canActivate: [RandomGuard],
    canLoad: [RandomGuard]
  }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes)
  ],
  exports: [RouterModule],
  declarations: []
})
export class AppRoutingModule { }

JSON Web Token

We came to the point where we have secured the routes in our application. The next step is to think about HTTP requests that the application sends to the server. If we only prevent the user from performing forbidden actions in our application, we will still be prone to the unauthorized HTTP calls that could be executed by the user, for example with any other HTTP client. Because of that, what is more important in securing a web application is making sure that the unauthorized server requests are not allowed. To make it possible for the server to recognize if the request is coming from an authorized user, we can attach an additional HTTP header indicating that fact. Here is the place where JSON Web Tokens (JWT) come into play.

The general idea standing behind JWT is to securely transmit information between parties. In our case, it is the user’s identity along with his rights, transmitted between the client (browser) and the server. When the user logs in, sending login query to the server, he receives back a JWT (aka access token) signed by the server with a private key. This private key should be known only to the server as it allows the server later to verify that the token is legitimate. When JWT is transmitted between the browser and the server, it is encoded with Base64 algorithm, that makes it look like a string of random characters (nothing could be further from the truth!). If you take a JWT and decode it with Base64 you will find a JSON object. Below you can find a decoded content of a JWT from our example application. On jwt.io you can play with JWT online.

Every JWT is composed of 3 blocks: header, payload, and signature. The header defines the type of the token and the used algorithm. The payload is the place where we put the data we want to securely transmit. In this case, we have a username, role, issuing timestamp (iat) and expiration timestamp (exp). The last block (HMACSHA256 function) is a signature generated with HMAC and SHA-256 algorithms. The signature guarantees not only that the token was created by a known party, but also the token’s integrity.

Integrity is the assurance of the accuracy and consistency of the data over its lifetime. In the case of JWT token, it means that it has not been altered during the transmission.

{
  "alg":"HS256",
  "typ":"JWT"
}
{
  "username": "user",
  "role": "admin",
  "iat": 1556172533,
  "exp": 1556173133
}
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  SECRET!
)

When the user successfully logs into the application and receives an access token, it has to be persisted somehow by the application. We can use for example local storage of the browser to save that token. It is fairly convenient and easy to implement, but it’s prone to XSS attacks. Another approach could be to use HttpOnly Cookie which is considered safer than local storage. Once we have JWT persisted, we will be attaching it to outgoing requests in HTTP Header. Before we dive into that aspect, let’s take a look at another important characteristic of JWT.

At this point, it is worth taking a closer look at the self-contained nature of JWT. When the server receives HTTP requests with JWT Access Token, it does not have to ask any persistence layer (for example database) for the verification of users rights. Those rights are inside the token. And since we guarantee authenticity and integrity of Access Token we can trust the information inside it. This is a really interesting feature of JWT because it opens the door for higher scalability of the system. Alternative scenarios would require saving some session id on the backend side and asking for it each and every time there is a need to authorize the request. Having self-contained Access Token, we don’t have to replicate token among server clusters or implement sticky sessions.

Http interceptor

Once we have our Access Token (JWT) persisted after user logs into the application, we want to use it to authorize outgoing requests. One approach could be to simply update every service that communicates with API to enrich requests with additional HTTP Header. This will result in a lot of duplicated code comparing to approach with HTTP Interceptor. The goal of HTTP Interceptor is to apply some processing logic to every outgoing request in the application.

Creating an HTTP interceptor is quite similar to creating a Router Guard. We need to have a class that implements a specific interface with the required method. In this case, it is HttpInterceptor with intercept method. Take a look at following code snippet with the interceptor from our example application. First, we want to check if the token is available with this.authService.getJwtToken(). If we have a token, we set an appropriate HTTP header. This code also contains error handling logic, which will be described later in this article.

@Injectable()
export class TokenInterceptor implements HttpInterceptor {

  constructor(public authService: AuthService) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    if (this.authService.getJwtToken()) {
      request = this.addToken(request, this.authService.getJwtToken());
    }

    return next.handle(request).pipe(catchError(error => {
      if (error instanceof HttpErrorResponse && error.status === 401) {
        return this.handle401Error(request, next);
      } else {
        return throwError(error);
      }
    }));
  }

  private addToken(request: HttpRequest<any>, token: string) {
    return request.clone({
      setHeaders: {
        'Authorization': `Bearer ${token}`
      }
    });
  }
}

Having implemented our interceptor, it is necessary to register it as a provider with HTTP_INTERCEPTORS token in Angular module.

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

@NgModule({
  // declarations...
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: TokenInterceptor,
      multi: true
    }
  ]
  // imports...
})
export class AuthModule { }

Refresh Token

Taking into account that JWT is self-contained we need to think about one more thing - there is no way to invalidate it! If someone other than us gets into possession of the token there is very little we can do about it. That’s why it is a good idea to always give the token short time of validity. There are no strict rules of how long a token should live and it depends on the system requirements. A good starting point could be to have a token that is only valid for 15 minutes. After that time server would not consider this token valid and would not authorize requests with it.

So here comes another challenge - we don’t want to force the user to login into the application, let’s say, every 15 minutes. The solution to this problem is a Refresh Token. This kind of token lives somewhere on the server side (database, in-memory cache, etc) and is associated with the particular user’s session. It is important to notice that this token differs from JWT in many ways. First, it is not self-contained - it can be as simple as a unique random string. Second, we need to have it stored to be able to verify if user’s session is still alive. This gives us an ability to invalidate the session by simply removing the associated pair of [user, refresh_token]. When there is an incoming request with Access Token that has become invalid, the application can send a Refresh Token to obtain a new Access Token. If the user’s session is still alive, the server would respond with a new valid JWT. In our example, we will be sending Refresh Token transparently for the user, so that he is not aware of the refreshing process.

Let’s get back to our interceptor. If you remember from the previous code snippet, in case of HTTP 401 Error (Unauthorized) we have a special method handle401Error for handling this situation. Here comes a tricky part - we want to queue all HTTP requests in case of refreshing. This means that if the server responds with 401 Error, we want to start refreshing, block all requests that may happen during refreshing, and release them once refreshing is done. To be able to block and release requests during the refreshing, we will use BehaviorSubject as a semaphore.

First, we check if refreshing has not already started and set isRefreshing variable to true and populate null into refreshTokenSubject behavior subject. Later, the actual refreshing request starts. In case of success, isRefreshing is set to false and received JWT token is placed into the refreshTokenSubject. Finally, we call next.handle with the addToken method to tell interceptor that we are done with processing this request. In case the refreshing is already happening (the else part of the if statement), we want to wait until refreshTokenSubject contains value other than null. Using filter(token => token != null) will make this trick! Once there is some value other than null (we expect new JWT inside) we call take(1) to complete the stream. Finally, we can tell the interceptor to finish processing this request with next.handle.

private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);

private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
  if (!this.isRefreshing) {
    this.isRefreshing = true;
    this.refreshTokenSubject.next(null);

    return this.authService.refreshToken().pipe(
      switchMap((token: any) => {
        this.isRefreshing = false;
        this.refreshTokenSubject.next(token.jwt);
        return next.handle(this.addToken(request, token.jwt));
      }));

  } else {
    return this.refreshTokenSubject.pipe(
      filter(token => token != null),
      take(1),
      switchMap(jwt => {
        return next.handle(this.addToken(request, jwt));
      }));
  }
}

As you see, the combination of Access Token and Refresh Token is a tradeoff between scalability and security. Restricting the validity time of Access Token decreases the risk of an unwanted person using it, but using Refresh Token requires statefulness on the server.

AuthService

The last missing part of our solution is AuthService. This will be the place where we implement all the logic to handle logging in and out. Below you can find the source of that service and we will analyze it step by step.

Let’s start with the login method. Here we use HttpClient to execute post call to the server and apply some operators with pipe() method. By using tap() operator we are able to execute the desired side effect. On successful post method execution, we should receive Access Token and Refresh Token. The side effect we want to execute is to store these tokens calling doLoginUser. In this example, we make use of localstorage. Once stored, the value in the stream is mapped to true in order for the consumer of that stream to know that the operation succeeded. Finally, in case of error, we show the alert and return observable of false.

Side effect is a term used in Functional Programming. This concept is opposite to functional purity which means that there are no state changes in the system and the function always returns the result based on its inputs (regardless of the system state). If there is a state change (for example variable change) we call it side effect.
Implementation of the logout method is basically the same, apart from the fact, that inside of the request’s body we send refreshToken. This will be used by the server to identify who is attempting to log out. Then, the server will remove the pair of [user, refresh_token] and refreshing will not be possible anymore. Yet, Access Token will still be valid until it expires, but we remove it from the localstorage.

@Injectable({
  providedIn: 'root'
})
export class AuthService {

  private readonly JWT_TOKEN = 'JWT_TOKEN';
  private readonly REFRESH_TOKEN = 'REFRESH_TOKEN';
  private loggedUser: string;

  constructor(private http: HttpClient) {}

  login(user: { username: string, password: string }): Observable<boolean> {
    return this.http.post<any>(`${config.apiUrl}/login`, user)
      .pipe(
        tap(tokens => this.doLoginUser(user.username, tokens)),
        mapTo(true),
        catchError(error => {
          alert(error.error);
          return of(false);
        }));
  }

  logout() {
    return this.http.post<any>(`${config.apiUrl}/logout`, {
      'refreshToken': this.getRefreshToken()
    }).pipe(
      tap(() => this.doLogoutUser()),
      mapTo(true),
      catchError(error => {
        alert(error.error);
        return of(false);
      }));
  }

  isLoggedIn() {
    return !!this.getJwtToken();
  }

  refreshToken() {
    return this.http.post<any>(`${config.apiUrl}/refresh`, {
      'refreshToken': this.getRefreshToken()
    }).pipe(tap((tokens: Tokens) => {
      this.storeJwtToken(tokens.jwt);
    }));
  }

  getJwtToken() {
    return localStorage.getItem(this.JWT_TOKEN);
  }

  private doLoginUser(username: string, tokens: Tokens) {
    this.loggedUser = username;
    this.storeTokens(tokens);
  }

  private doLogoutUser() {
    this.loggedUser = null;
    this.removeTokens();
  }

  private getRefreshToken() {
    return localStorage.getItem(this.REFRESH_TOKEN);
  }

  private storeJwtToken(jwt: string) {
    localStorage.setItem(this.JWT_TOKEN, jwt);
  }

  private storeTokens(tokens: Tokens) {
    localStorage.setItem(this.JWT_TOKEN, tokens.jwt);
    localStorage.setItem(this.REFRESH_TOKEN, tokens.refreshToken);
  }

  private removeTokens() {
    localStorage.removeItem(this.JWT_TOKEN);
    localStorage.removeItem(this.REFRESH_TOKEN);
  }
}

Summary

We have covered the most important pieces of designing an authorization mechanism on the frontend side in Angular. You can find full sources of frontend and backend side under GitHub repositories:

Using JWT as an Access Token has a lot of benefits and it’s fairly simple to implement. However, you should be aware of the limitations and possible XSS Attacks. The way to minimize the risk is to use HttpOnly Cookies to store the tokens.

#angular #security

What is GEEK

Buddha Community

Angular JWT Authorization
Were  Joyce

Were Joyce

1622798007

Angular 12 + Spring Boot: JWT Authentication example | Spring Security

In this tutorial, I will show you how to build a full stack Angular 12 + Spring Boot JWT Authentication example. The back-end server uses Spring Boot with Spring Security for JWT Authentication & Role based Authorization, Spring Data JPA for interacting with database. The front-end will be built using Angular 12 with HttpInterceptor & Form validation.

Related Posts:

– Angular 12 + Spring Boot: CRUD example

– Angular 12 + Spring Boot: File upload example

– Spring Boot, MongoDB: JWT Authentication with Spring Security

Contents [hide]

#angular #full stack #spring #angular #angular 12 #authentication #authorization #jwt #login #registration #security #spring boot #spring security #token based authentication

Christa  Stehr

Christa Stehr

1598940617

Install Angular - Angular Environment Setup Process

Angular is a TypeScript based framework that works in synchronization with HTML, CSS, and JavaScript. To work with angular, domain knowledge of these 3 is required.

  1. Installing Node.js and npm
  2. Installing Angular CLI
  3. Creating workspace
  4. Deploying your First App

In this article, you will get to know about the Angular Environment setup process. After reading this article, you will be able to install, setup, create, and launch your own application in Angular. So let’s start!!!

Angular environment setup

Install Angular in Easy Steps

For Installing Angular on your Machine, there are 2 prerequisites:

  • Node.js
  • npm Package Manager
Node.js

First you need to have Node.js installed as Angular require current, active LTS or maintenance LTS version of Node.js

Download and Install Node.js version suitable for your machine’s operating system.

Npm Package Manager

Angular, Angular CLI and Angular applications are dependent on npm packages. By installing Node.js, you have automatically installed the npm Package manager which will be the base for installing angular in your system. To check the presence of npm client and Angular version check of npm client, run this command:

  1. npm -v

Installing Angular CLI

  • Open Terminal/Command Prompt
  • To install Angular CLI, run the below command:
  1. npm install -g @angular/cli

installing angular CLI

· After executing the command, Angular CLI will get installed within some time. You can check it using the following command

  1. ng --version

Workspace Creation

Now as your Angular CLI is installed, you need to create a workspace to work upon your application. Methods for it are:

  • Using CLI
  • Using Visual Studio Code
1. Using CLI

To create a workspace:

  • Navigate to the desired directory where you want to create your workspace using cd command in the Terminal/Command prompt
  • Then in the directory write this command on your terminal and provide the name of the app which you want to create. In my case I have mentioned DataFlair:
  1. Ng new YourAppName

create angular workspace

  • After running this command, it will prompt you to select from various options about the CSS and other functionalities.

angular CSS options

  • To leave everything to default, simply press the Enter or the Return key.

angular setup

#angular tutorials #angular cli install #angular environment setup #angular version check #download angular #install angular #install angular cli

Roberta  Ward

Roberta Ward

1593184320

Basics of Angular: Part-1

What is Angular? What it does? How we implement it in a project? So, here are some basics of angular to let you learn more about angular.

Angular is a Typescript-based open-source front-end web application platform. The Angular Team at Google and a community of individuals and corporations lead it. Angular lets you extend HTML’s syntax to express your apps’ components clearly. The angular resolves challenges while developing a single page and cross-platform applications. So, here the meaning of the single-page applications in angular is that the index.html file serves the app. And, the index.html file links other files to it.

We build angular applications with basic concepts which are NgModules. It provides a compilation context for components. At the beginning of an angular project, the command-line interface provides a built-in component which is the root component. But, NgModule can add a number of additional components. These can be created through a template or loaded from a router. This is what a compilation context about.

What is a Component in Angular?

Components are key features in Angular. It controls a patch of the screen called a view. A couple of components that we create on our own helps to build a whole application. In the end, the root component or the app component holds our entire application. The component has its business logic that it does to support the view inside the class. The class interacts with the view through an API of properties and methods. All the components added by us in the application are not linked to the index.html. But, they link to the app.component.html through the selectors. A component can be a component and not only a typescript class by adding a decorator @Component. Then, for further access, a class can import it. The decorator contains some metadata like selector, template, and style. Here’s an example of how a component decorator looks like:

@Component({
    selector: 'app-root',
    templateUrl: 'app.component.html',
    styleUrls: ['app.component.scss']
})

Role of App Module

Modules are the package of functionalities of our app. It gives Angular the information about which features does my app has and what feature it uses. It is an empty Typescript class, but we transform it by adding a decorator @NgModule. So, we have four properties that we set up on the object pass to @NgModule. The four properties are declarations, imports, providers, and bootstrap. All the built-in new components add up to the declarations array in @NgModule.

@NgModule({
declarations: [
  AppComponent,
],
imports: [
  BrowserModule,
  HttpClientModule,
  AppRoutingModule,
  FormsModule
],
bootstrap: [AppComponent]
})

What is Data Binding?

Data Binding is the communication between the Typescript code of the component and the template. So, we have different kinds of data binding given below:

  • When there is a requirement to output data from our Typescript code in the HTML template. String interpolation handles this purpose like {{data}} in HTML file. Property Binding is also used for this purpose like [property] = “data”.
  • When we want to trigger any event like clicking a button. Event Binding works while we react to user events like (event) = “expression”.
  • When we can react to user events and output something at the same time. Two-way Binding is used like [(ngModel)] = “data”.

image for understanding data binding

#angular #javascript #tech blogs #user interface (ui) #angular #angular fundamentals #angular tutorial #basics of angular

Ayyaz Zafar

1624138795

Angular Material Autocomplete - Multiple Use Cases covered

Learn How to use Angular Material Autocomplete Suggestions Search Input. I covered multiple use cases.

Please watch this video. I hope this video would be helpful for you to understand it and use it in your projects

Please subscribe: https://www.youtube.com/channel/UCL5nKCmpReJZZMe9_bYR89w

#angular #angular-material #angular-js #autocomplete #angular-material-autocomplete #angular-tutorial

Lindsey  Koepp

Lindsey Koepp

1595221620

Angular and Laravel 7 Password Reset for JWT Tutorial

In this tutorial, we will learn how to securely reset a password by consuming Laravel 7 JWT auth API with Angular.

This is the second tutorial of Laravel JWT authentication, and preferably we will learn how to create a password reset functionality in Angular using Laravel 7 REST API.

Reset password is ah act of cancelling the existing password for a specific account at a website, service, or device, and then generating a new one.

Tutorial Objective

  • Create two laravel APIs, for making a reset password request other for resetting the password.
  • Handle password reset request with the token, to restrain redundancy.
  • Send password reset mail via mailtrap.io in laravel with a valid token.
  • Handle laravel API through angular service with full-on consensus between backend and frontend.

Table of Contents

  1. Clone Laravel Token-Based Authentication Repo
  2. Configure Mailtrap
  3. Reset Password Request
  4. Reset Password

Clone Laravel Token-Based Authentication Repo

To comprehend or even start working on the pre-built repo, kindly clone the repo using the following command:

git clone https://github.com/SinghDigamber/laravel-angular-jwt-auth.git

BashCopy

The project simultaneously contains backend (Laravel) and frontend (Angular) folders, write your code accordingly.

A quick recap about the topics that we have covered in laravel authentication project.

  • User login and signup in laravel and angular.
  • Building secure laravel API for secure user authentication using JWT token.
  • Password hashing to store the password securely.
  • Consuming the laravel API in an angular app.
  • Set JWT token in headers while logging in.
  • Refresh token at a specific interval to add the security.
  • Logout from laravel app.

To assimilate the entire authentication process, please read this whole article:

JWT Authentication in Laravel with Angular: User Authentication & Registration

#angular #laravel #jwt #api #angular