Как создать Http-перехватчик в Angular Framework

Вступление

Фреймворк Angular стал одним из самых известных фреймворков javascript за последние несколько лет. Фактически, этот инструмент содержит множество функций и возможностей, которые очень полезны для веб-разработки.

В этой статье мы покажем вам, как создать перехватчик Http в фреймворке Angular.

Что, черт возьми, такое Http-перехватчик?

Сначала давайте сделаем это просто.

Все мы знаем, что с помощью Angular мы можем выполнять HTTP-запросы к любой стороне сервера на основе подхода REST с использованием методов (GET, POST, PUT, DELETE), поэтому в современных веб-архитектурах работа с HTTP-запросами становится все более сложной задачей. иногда нам нужно добавить дополнительную информацию к запросу перед его отправкой на сервер, и мы можем взять в качестве примера веб-сервисы RESTful, которые используют аутентификацию на основе токенов в качестве подхода безопасности, который фактически основан на отправке запросов на сервер и добавлении того, что мы называем acces в заголовке HTTP-запроса, после чего запрос будет перехвачен промежуточным программным обеспечением на стороне сервера, чтобы проверить, действителен ли токен, и предоставить доступ для захвата или сохранения данных.

Теперь проблема в том, что мы должны добавить этот токен доступа вручную, используя специальные заголовки, к каждому отдельному HTTP-запросу в нашем приложении Angular и точно к каждому провайдеру услуг, который у нас есть, где мы обычно используем HttpClient для выполнения запросов.

Чтобы избежать этой проблемы, мы собираемся использовать Http-перехватчик, который является новой функцией, включенной в Angular, которая помогает нам перехватывать HTTP-запросы и автоматически прикреплять любую дополнительную информацию.

Начиная

Для начала мы собираемся создать новое приложение Angular, поэтому в вашей системе должны быть установлены node Js и Angular CLI.

Чтобы создать новый проект, откройте командную строку и напишите эту команду

ng new HttpInterceptorApp

теперь переместитесь под директорию проекта и ленту

ng serve

откройте браузер и перейдите по адресу http: // localhost: 4200 /, и вы увидите эту страницу.

На данный момент все выглядит отлично.

Теперь то, что мы собираемся сделать, это то, что мы попытаемся объединить Angular и Node Js, чтобы создать простую систему аутентификации, чтобы получить токен доступа с сервера.

Сначала клонируйте этот репозиторий (https://github.com/medaymenTN/JWTNodeJS), затем перейдите в каталог проекта и запустите (npm install), после чего запустите сервер node js с помощью (node ​​index.js)

если вы хотите узнать больше об аутентификации на основе токенов, вы можете проверить наше последнее руководство по ссылке ниже: (https://medium.com/@mohamedaymen.ourabi11/securing-your-node-js-api-with-json- web-token-de27c33f999b ).

Теперь в приложении angular мы собираемся построить простую систему аутентификации.

В файле app.component.html добавьте эти несколько строк.

<input type="text" name="username" id="username" [(ngModel)]="username">
<br>
<input type="password" name="password" id="password" [(ngModel)]="password">
<br>
<input type="button" value="Login" (click)="Login()">
<br>
<input type="button" value="Display list" (click))="DisplayList()" />

(Не забудьте добавить FormsModule в свой app.module.ts)

Таким образом, это в основном простой HTML-код, в котором у нас есть два вводимого текста и две кнопки, одна для входа в систему, а другая будет использоваться для отображения списка продуктов, которые мы собираемся получить с сервера, поэтому для этого мы должны прикрепить токен к запросу GET перед его отправкой на сервер.

В нашем проекте и с помощью командной строки создайте новый сервис под названием Auth

Теперь создайте файл с именем interceptor.ts и добавьте эти несколько строк

import { Injectable } from "@angular/core";
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent } from "@angular/common/http";
import { Observable } from "rxjs/Observable";
@Injectable()
export class Interceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      
    const customReq = request.clone({
    
    });
    return next.handle(customReq);
  }
}

Теперь перейдите в файл app.module.ts и импортируйте HttpClientModule, HTTP_INTERCEPTOR и перехватчик, чтобы ваш файл выглядел так

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {FormsModule} from '@angular/forms'
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppComponent } from './app.component';
import { Interceptor } from './interceptor';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule
  ],
  providers: [
    AuthService,
    { provide: HTTP_INTERCEPTORS, useClass: Interceptor, multi: true }  
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Вернитесь в свой Auth.service.ts и создайте эти два метода

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class AuthService {
  constructor(private Http:HttpClient) { }

  Authentication(username:string,password:string){
    let json = {username:username,password:password}
    return this.Http.post("http://localhost:3000/authenticate ",json); 
  }

  GetAllProducts(){
    return this.Http.get("http://localhost:3000/api/getAllProducts")
  }
}

Честно говоря, для того, чтобы все было хорошо организовано, лучше создать другой сервис, в который вы должны поместить метод GetAllProducts, но для этого урока мы просто сохраним его в сервисе Auth.

теперь в App.component.ts создайте два метода Login () и DisplayList (), которые будут обрабатывать события нажатия кнопки

import { Component } from '@angular/core';
import { AuthService } from './auth.service';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
 private username:string = ""
 private password:string = ""
       constructor(private authService:AuthService) {
         
       }
       Login(){
         this.authService.Authentication(this.username,this.password).subscribe(
           (data)=>{
           
            if(data["token"] != null){

              // retreive the access token from the server
           console.log(data["token"])

            // store the token in the localStorage 
            localStorage.setItem("access-token",data["token"])
           
            }else{
              console.log("check your credentials !!")
            }
           }
         )
       }
       DisplayList(){
         this.authService.GetAllProducts().subscribe(
           (data)=>{

              // display list in the console 
                 console.log(data)
           }
         )
       }
}

А теперь самое лучшее !!

чтобы прикрепить токен доступа к каждому отдельному HTTP-запросу, мы обновим наш файл interceptor.ts, чтобы он выглядел так

import { Injectable, Injector } from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpHeaders} from '@angular/common/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/observable/throw'
import 'rxjs/add/operator/catch';
@Injectable()
export class Interceptor implements HttpInterceptor {
  constructor() {}
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

 if(localStorage.getItem('access-token') != null) 
{
   const token =  localStorage.getItem('access-token');
// if the token is  stored in localstorage add it to http header
const headers = new HttpHeaders().set("access-token", token);
   //clone http to the custom AuthRequest and send it to the server 

const AuthRequest = request.clone( { headers: headers});
return next.handle(AuthRequest)
   }else {
     return next.handle(request);
   }
  }
}

В нашем браузере попробуйте войти в систему, используя эти учетные данные (aymen, 123), после этого откройте консоль браузера, чтобы вы могли видеть, что мы успешно вошли в систему и у нас есть токен

Теперь перейдите в application == ›localstorage, и вы увидите, что токен также сохраняется.

Теперь давайте попробуем отобразить список продуктов с сервера, поэтому нажмите кнопку Показать список и посмотрим, что будет.

Все выглядит нормально, токен подтвержден промежуточным программным обеспечением сервера, и у нас отображаются наши продукты.

теперь, чтобы лучше взглянуть на то, что перехватчик пошел в сеть и открыл фрейм относительно запроса getAllProducts

Теперь мы можем видеть, что перехватчик автоматически добавил токен доступа в заголовок запроса, обратите внимание, что эта операция будет выполняться для каждого отдельного запроса, который мы собираемся выполнить на нашем сервере с помощью службы angular HttpClient.

Заключение

Http intrecptor - очень красивый инструмент, который помогает нам настраивать наши HTTP-запросы и выполнять любые операции, такие как добавление пользовательских заголовков или обновление данных перед их отправкой на сервер, обратите внимание, что это не единственная функция, предоставляемая Angular, но есть много инструменты, которые эквивалентны этому и могут быть очень полезны при создании веб-приложений

Вы можете найти проект по ссылке ниже: https://github.com/medaymenTN/AngularHttpInterceptor