Tokenbasierte Authentifizierung mit Angular und Node

王林
Freigeben: 2023-09-01 14:01:06
Original
1331 Leute haben es durchsucht

Tokenbasierte Authentifizierung mit Angular und Node

Authentifizierung ist einer der wichtigsten Teile jeder Webanwendung. In diesem Tutorial werden tokenbasierte Authentifizierungssysteme und ihre Unterschiede zu herkömmlichen Anmeldesystemen erläutert. Am Ende dieses Tutorials sehen Sie eine voll funktionsfähige Demo, die in Angular und Node.js geschrieben wurde.

Traditionelles Authentifizierungssystem

Bevor wir zu tokenbasierten Authentifizierungssystemen übergehen, werfen wir einen Blick auf traditionelle Authentifizierungssysteme.

  1. Der Benutzer gibt Benutzernamen und Passwort in das Anmeldeformular ein und klickt auf Anmelden.
  2. Nachdem Sie die Anfrage gestellt haben, authentifizieren Sie den Benutzer im Backend, indem Sie die Datenbank abfragen. Wenn die Anfrage gültig ist, wird eine Sitzung mit den aus der Datenbank erhaltenen Benutzerinformationen erstellt und die Sitzungsinformationen werden im Antwortheader zurückgegeben, sodass die Sitzungs-ID im Browser gespeichert wird.
  3. Stellt Sitzungsinformationen für den Zugriff auf eingeschränkte Endpunkte in Ihrer Anwendung bereit.
  4. Wenn die Sitzungsinformationen gültig sind, erlauben Sie dem Benutzer, auf den angegebenen Endpunkt zuzugreifen und mit gerendertem HTML-Inhalt zu antworten.

Tokenbasierte Authentifizierung mit Angular und Node

So weit so gut. Die Webanwendung funktioniert einwandfrei und kann Benutzer authentifizieren, damit sie auf eingeschränkte Endpunkte zugreifen können. Aber was passiert, wenn Sie einen anderen Client für Ihre Anwendung entwickeln möchten (z. B. einen Android-Client)? Können Sie mit Ihrer aktuellen Anwendung mobile Clients authentifizieren und eingeschränkte Inhalte bereitstellen? So wie es aussieht, nein. Dafür gibt es vor allem zwei Gründe:

  1. Sitzung und Cookies haben für mobile Anwendungen keine Bedeutung. Sie können serverseitig erstellte Sitzungen oder Cookies nicht mit mobilen Clients teilen.
  2. Gibt in der aktuellen Anwendung den gerenderten HTML-Code zurück. Bei mobilen Clients müssen Sie als Antwort etwas wie JSON oder XML einbinden.

In diesem Fall benötigen Sie eine mandantenunabhängige Anwendung.

Tokenbasierte Authentifizierung

Bei der tokenbasierten Authentifizierung werden keine Cookies und Sitzungen verwendet. Das Token wird zur Authentifizierung des Benutzers bei jeder Anfrage an den Server verwendet. Lassen Sie uns das erste Szenario mithilfe der tokenbasierten Authentifizierung neu gestalten.

Es wird der folgende Kontrollfluss verwendet:

  1. Der Benutzer gibt Benutzernamen und Passwort in das Anmeldeformular ein und klickt auf Anmelden.
  2. Nachdem Sie die Anfrage gestellt haben, authentifizieren Sie den Benutzer im Backend, indem Sie eine Abfrage in der Datenbank durchführen. Wenn die Anfrage gültig ist, wird anhand der aus der Datenbank erhaltenen Benutzerinformationen ein Token erstellt und dann im Antwortheader zurückgegeben, damit wir den Token-Browser im lokalen Speicher speichern können.
  3. Geben Sie in jedem Anforderungsheader Token-Informationen an, um auf eingeschränkte Endpunkte in Ihrer Anwendung zuzugreifen.
  4. Wenn das aus den Anforderungsheaderinformationen erhaltene Token gültig ist, lassen Sie den Benutzer auf den angegebenen Endpunkt zugreifen und mit JSON oder XML antworten.

In diesem Fall geben wir weder die Sitzung noch Cookies zurück, noch geben wir HTML-Inhalte zurück. Das bedeutet, dass wir diese Architektur für jede kundenspezifische Anwendung nutzen können. Die architektonische Architektur können Sie unten sehen:

Tokenbasierte Authentifizierung mit Angular und Node

Was ist das also für ein JWT?

JWT

JWT steht für JSON Web Token und ist das im Autorisierungsheader verwendete Tokenformat. Dieser Token hilft Ihnen, die Kommunikation zwischen den beiden Systemen sicher zu gestalten. Für die Zwecke dieses Tutorials werden wir JWT in „Bearer Token“ umformulieren. Ein Inhabertoken besteht aus drei Teilen: Header, Nutzlast und Signatur.

  • Header ist der Teil des Tokens, der den Tokentyp und die Verschlüsselungsmethode enthält, die ebenfalls mit Base-64 verschlüsselt wird.
  • Payloadenthält Informationen. Sie können jede Art von Daten wie Benutzerinformationen, Produktinformationen usw. eingeben, die alle mit Base-64-Verschlüsselung gespeichert werden.
  • Eine Signatur besteht aus einer Kombination aus Header, Payload und Schlüssel. Der Schlüssel muss serverseitig sicher aufbewahrt werden.

Sie können das JWT-Schema und das Beispiel-Token unten sehen:

Tokenbasierte Authentifizierung mit Angular und Node

Sie müssen keinen Bearer-Token-Generator implementieren, da Sie etablierte Pakete für viele Sprachen finden. Einige davon könnt ihr unten sehen:

Node.js https://github.com/auth0/node-jsonwebtoken
PHP http://github.com/firebase/php-jwt
Java http://github.com/auth0/java-jwt
红宝石 https://github.com/jwt/ruby-jwt
.NET https://github.com/auth0/java-jwt
Python http://github.com/progrium/pyjwt/

Ein praktisches Beispiel

Nachdem wir einige grundlegende Informationen zur tokenbasierten Authentifizierung behandelt haben, können wir nun zu einem praktischen Beispiel übergehen. Schauen Sie sich die Architektur unten an, dann analysieren wir sie genauer:

Tokenbasierte Authentifizierung mit Angular und Node

  1. Mehrere Clients (z. B. Webanwendungen oder mobile Clients) stellen für einen bestimmten Zweck Anfragen an die API.
  2. Anfragen werden an Dienste wie https://api.yourexampleapp.com gestellt. Wenn viele Benutzer die Anwendung verwenden, sind möglicherweise mehrere Server erforderlich, um die angeforderten Vorgänge auszuführen.
  3. Hier wird ein Load Balancer verwendet, um Anfragen so zu verteilen, dass sie optimal zu den Anwendungsservern im Backend passen. Wenn Sie eine Anfrage an https://api.yourexampleapp.com stellen, bearbeitet der Load Balancer zunächst die Anfrage und leitet den Client dann an einen bestimmten Server weiter.
  4. Es gibt eine Anwendung und die Anwendung wird auf mehreren Servern bereitgestellt (Server-1, Server-2, ..., Server-n). Immer wenn eine Anfrage an https://api.yourexampleapp.com gestellt wird, fängt die Backend-Anwendung die Anfrage-Header ab und extrahiert die Token-Informationen aus dem Autorisierungs-Header. Dieses Token wird für Datenbankabfragen verwendet. Wenn dieses Token gültig ist und über die erforderlichen Berechtigungen für den Zugriff auf den angeforderten Endpunkt verfügt, wird der Vorgang fortgesetzt. Wenn nicht, wird der Antwortcode 403 zurückgegeben (der den Status „Verboten“ anzeigt).

Vorteile

Tokenbasierte Authentifizierung bietet mehrere Vorteile, die schwerwiegende Probleme lösen. Hier sind einige davon:

Kundenunabhängiger Service

Bei der tokenbasierten Authentifizierung wird das Token über den Anforderungsheader übertragen, anstatt die Authentifizierungsinformationen in der Sitzung oder im Cookie beizubehalten. Das heißt, es gibt keinen Staat. Sie können von jedem Clienttyp, der HTTP-Anfragen stellen kann, Anfragen an den Server senden.

Content Delivery Network (CDN)

In den meisten aktuellen Webanwendungen wird die Ansicht im Backend gerendert und der HTML-Inhalt an den Browser zurückgegeben. Die Front-End-Logik hängt vom Back-End-Code ab.

Es besteht keine Notwendigkeit, solche Abhängigkeiten zu erstellen. Dies wirft mehrere Fragen auf. Wenn Sie beispielsweise mit einer Designagentur zusammenarbeiten, die Front-End-HTML, CSS und JavaScript implementiert, müssen Sie diesen Front-End-Code in Back-End-Code migrieren, damit einige Rendering- oder Füllvorgänge ausgeführt werden können. Nach einer Weile wird sich der von Ihnen gerenderte HTML-Inhalt stark von dem unterscheiden, was die Code-Agentur implementiert hat.

Bei der tokenbasierten Authentifizierung können Sie Ihr Front-End-Projekt getrennt von Ihrem Back-End-Code entwickeln. Ihr Backend-Code gibt eine JSON-Antwort anstelle von gerendertem HTML zurück, und Sie können eine minimierte, gezippte Version Ihres Frontend-Codes in ein CDN einfügen. Wenn Sie eine Webseite besuchen, wird der HTML-Inhalt vom CDN bereitgestellt und der Seiteninhalt wird vom API-Dienst mithilfe des Tokens im Autorisierungsheader aufgefüllt.

CSRF ist ein großes Problem in der modernen Netzwerksicherheit, da es nicht prüft, ob die Quelle der Anfrage vertrauenswürdig ist. Um dieses Problem zu lösen, verwenden Sie einen Token-Pool, um dieses Token bei jedem Formularbeitrag zu senden. Bei der tokenbasierten Authentifizierung wird das Token im Autorisierungsheader verwendet und CSRF enthält diese Informationen nicht.

Persistenter Token-Speicher

Wenn in einer Anwendung ein Sitzungs-Lese-, Schreib- oder Löschvorgang stattfindet, führt sie zumindest zum ersten Mal Dateivorgänge im temp-Ordner des Betriebssystems aus. Nehmen wir an, Sie haben mehrere Server und erstellen eine Sitzung auf dem ersten Server. Wenn Sie eine weitere Anfrage stellen und diese an einen anderen Server weitergeleitet wird, sind die Sitzungsinformationen nicht vorhanden und Sie erhalten die Antwort „Nicht autorisiert“. Ich weiß, dass Sie dieses Problem mit Sticky Sessions lösen können. Bei der tokenbasierten Authentifizierung wird diese Situation jedoch auf natürliche Weise gelöst. Es gibt kein Sticky-Session-Problem, da das Anforderungstoken bei jeder Anforderung auf jedem Server abgefangen wird.

Dies sind die häufigsten Vorteile der tokenbasierten Authentifizierung und Kommunikation. Damit ist die theoretische und architektonische Diskussion der tokenbasierten Authentifizierung abgeschlossen. Es ist Zeit, sich ein praktisches Beispiel anzusehen.

Beispielanwendung

Sie sehen zwei Anwendungen, die eine tokenbasierte Authentifizierung demonstrieren:

  1. Tokenbasiertes Authentifizierungs-Backend
  2. Token-basiertes Authentifizierungs-Frontend

Im Back-End-Projekt erfolgt die Service-Implementierung und die Service-Ergebnisse liegen im JSON-Format vor. Es gibt keine vom Dienst zurückgegebene Ansicht. Im Front-End-Projekt gibt es ein Angular-Projekt für das Front-End-HTML und dann wird die Front-End-Anwendung vom Angular-Dienst gefüllt, um Anfragen an den Back-End-Dienst zu stellen.

Tokenbasiertes Authentifizierungs-Backend

Im Backend-Projekt gibt es drei Hauptdateien:

  • package.json wird für das Abhängigkeitsmanagement verwendet.
  • models/User.js enthält ein Benutzermodell für Datenbankoperationen für Benutzer.
  • server.js wird für das Projekt-Bootstrapping und die Anforderungsverarbeitung verwendet.

Das ist es! Dieses Projekt ist sehr einfach, sodass Sie die Hauptkonzepte leicht verstehen können, ohne sich zu sehr damit befassen zu müssen.

{
    "name": "angular-restful-auth",
    "version": "0.0.1",
    "dependencies": {
        "body-parser": "^1.20.2",
        "express": "4.x",
        "express-jwt": "8.4.1",
        "jsonwebtoken": "9.0.0",
        "mongoose": "7.3.1",
        "morgan": "latest"
    },
    "engines": {
        "node": ">=0.10.0"
    }
}
Nach dem Login kopieren

package.json Enthält die Abhängigkeiten des Projekts: express für MVC, body-parserexpress 用于 MVC,body-parser 用于模拟 post Node.js 中的请求处理,morgan 用于请求日志记录,mongoose 用于我们的 ORM 框架连接到 MongoDB,和 jsonwebtoken 用于使用我们的用户模型创建 JWT 令牌。还有一个名为 engines

für Spott-Posts. Anfragebearbeitung in Node.js, morgan

für die Anforderungsprotokollierung, mongoose

für unser ORM-Framework Connect to MongoDB und jsonwebtoken wird verwendet, um mithilfe unseres Benutzermodells ein JWT-Token zu erstellen. Es gibt auch ein Attribut namens engines, das angibt, dass das Projekt mit der Node.js-Version >= 0.10.0 erstellt wurde. Dies ist nützlich für PaaS-Dienste wie Heroku. Wir werden dieses Thema auch in einem anderen Abschnitt besprechen.

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const UserSchema = new Schema({
  email: String,
  password: String,
  token: String
});

module.exports = mongoose.model('User', UserSchema);
Nach dem Login kopieren

Wir sagten, wir würden die Nutzlast des Benutzermodells verwenden, um das Token zu generieren. Dieses Modell hilft uns, Benutzeroperationen auf MongoDB durchzuführen. In

User.jsrequire wird das Benutzermuster definiert und das Benutzermodell mithilfe des Mongoose-Modells erstellt. Das Modell ist für Datenbankoperationen bereit.

Unsere Abhängigkeiten sind definiert, unser Benutzermodell ist definiert. Lassen Sie uns nun alles zusammenfügen, um einen Dienst zu erstellen, der bestimmte Anforderungen bearbeitet. 3001。之后,包含了User模型,并建立了数据库连接,以进行一些用户操作。不要忘记为数据库连接 URL 定义一个环境变量 MONGO_URL

// Required Modules
const express    = require("express");
const morgan     = require("morgan");
const bodyParser = require("body-parser");
const jwt        = require("jsonwebtoken");
const mongoose   = require("mongoose");
const app        = express();
Nach dem Login kopieren

In Node.js können Sie

verwenden, um Module in Ihr Projekt einzubinden. Zuerst müssen wir die notwendigen Module in das Projekt importieren:

const port = process.env.PORT || 3001;
const User     = require('./models/User');

// Connect to DB
mongoose.connect(process.env.MONGO_URL);
Nach dem Login kopieren
​ 🎜Unser Service wird über einen bestimmten Port bereitgestellt. Sie können es verwenden, wenn eine Portvariable in den Systemumgebungsvariablen definiert ist oder wir einen Port definiert haben 🎜. 🎜
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(morgan("dev"));
app.use(function(req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
    next();
});

Nach dem Login kopieren
​ 🎜Im obigen Abschnitt haben wir einige Konfigurationen mit Express vorgenommen, um die HTTP-Anforderungsverarbeitung in Node zu simulieren. Wir erlauben Anfragen aus verschiedenen Domänen, um ein mandantenunabhängiges System zu entwickeln. Wenn Sie dies nicht zulassen, lösen Sie CORS-Fehler (Cross Origin Request Sharing) in Ihrem Webbrowser aus. 🎜
  • Access-Control-Allow-Origin 允许所有域。
  • 您可以向此服务发送 POSTGET 请求。
  • X-Requested-Withcontent-type 标头是允许的。
app.post('/authenticate', async function(req, res) {
    try {
      const user = await User.findOne({ email: req.body.email, password: req.body.password }).exec();
      if (user) {
        res.json({
          type: true,
          data: user,
          token: user.token
        });
      } else {
        res.json({
          type: false,
          data: "Incorrect email/password"
        });
      }
    } catch (err) {
      res.json({
        type: false,
        data: "Error occurred: " + err
      });
    }
  });
Nach dem Login kopieren
 

我们已经导入了所有必需的模块并定义了我们的配置,所以现在是时候定义请求处理程序了。在上面的代码中,每当你使用用户名和密码向 /authenticate 发出 POST 请求时,你都会得到一个 JWT 令牌。首先,使用用户名和密码处理数据库查询。如果用户存在,则用户数据将与其令牌一起返回。但是如果没有与用户名和/或密码匹配的用户怎么办?

 app.post('/signin', async function(req, res) {
    try {
      const existingUser = await User.findOne({ email: req.body.email }).exec();
      if (existingUser) {
        res.json({
          type: false,
          data: "User already exists!"
        });
      } else {
        const userModel = new User();
        userModel.email = req.body.email;
        userModel.password = req.body.password;
        const savedUser = await userModel.save();
        savedUser.token = jwt.sign(savedUser.toObject(), process.env.JWT_SECRET);
        const updatedUser = await savedUser.save();
        res.json({
          type: true,
          data: updatedUser,
          token: updatedUser.token
        });
      }
    } catch (err) {
      res.json({
        type: false,
        data: "Error occurred: " + err
      });
    }
  });
Nach dem Login kopieren
 

当您使用用户名和密码向 /signin 发出 POST 请求时,将使用发布的用户信息创建一个新用户。在 14th 行,您可以看到使用 jsonwebtoken 模块生成了一个新的 JSON 令牌,该令牌已分配给 jwt 变量。认证部分没问题。如果我们尝试访问受限端点怎么办?我们如何设法访问该端点?

app.get('/me', ensureAuthorized, async function(req, res) {
    try {
      const user = await User.findOne({ token: req.token }).exec();
      res.json({
        type: true,
        data: user
      });
    } catch (err) {
      res.json({
        type: false,
        data: "Error occurred: " + err
      });
    }
  });
Nach dem Login kopieren
 

当您向 /me 发出 GET 请求时,您将获得当前用户信息,但为了继续请求的端点,确保Authorized函数将被执行。

function ensureAuthorized(req, res, next) {
    var bearerToken;
    var bearerHeader = req.headers["authorization"];
    if (typeof bearerHeader !== 'undefined') {
        var bearer = bearerHeader.split(" ");
        bearerToken = bearer[1];
        req.token = bearerToken;
        next();
    } else {
        res.send(403);
    }
}
Nach dem Login kopieren
 

在该函数中,拦截请求头,并提取authorization头。如果此标头中存在承载令牌,则该令牌将分配给 req.token 以便在整个请求中使用,并且可以使用 next( )。如果令牌不存在,您将收到 403(禁止)响应。让我们回到处理程序 /me,并使用 req.token 使用此令牌获取用户数据。每当您创建新用户时,都会生成一个令牌并将其保存在数据库的用户模型中。这些令牌是独一无二的。

对于这个简单的项目,我们只有三个处理程序。之后,您将看到:

process.on('uncaughtException', function(err) {
    console.log(err);
});
Nach dem Login kopieren
 

如果发生错误,Node.js 应用程序可能会崩溃。使用上面的代码,可以防止崩溃,并在控制台中打印错误日志。最后,我们可以使用以下代码片段启动服务器。

// Start Server
app.listen(port, function () {
    console.log( "Express server listening on port " + port);
});
Nach dem Login kopieren
 

总结一下:

  • 模块已导入。
  • 配置已完成。
  • 已定义请求处理程序。
  • 定义中间件是为了拦截受限端点。
  • 服务器已启动。

我们已经完成了后端服务。为了让多个客户端可以使用它,您可以将这个简单的服务器应用程序部署到您的服务器上,或者也可以部署在 Heroku 中。项目根文件夹中有一个名为 Procfile 的文件。让我们在 Heroku 中部署我们的服务。

Heroku 部署

您可以从此 GitHub 存储库克隆后端项目。

我不会讨论如何在 Heroku 中创建应用程序;如果您之前没有创建过 Heroku 应用程序,可以参考这篇文章来创建 Heroku 应用程序。创建 Heroku 应用程序后,您可以使用以下命令将目标添加到当前项目:

git remote add heroku <your_heroku_git_url>
Nach dem Login kopieren

现在您已经克隆了一个项目并添加了一个目标。在 git addgit commit 之后,您可以通过执行 git push heroku master 将代码推送到 Heroku。当您成功推送项目时,Heroku 将执行 npm install 命令将依赖项下载到 Heroku 上的 temp 文件夹中。之后,它将启动您的应用程序,您可以使用 HTTP 协议访问您的服务。

基于令牌的-auth-frontend

在前端项目中,您将看到一个 Angular 项目。在这里,我只提及前端项目中的主要部分,因为 Angular 不是一个教程可以涵盖的内容。

您可以从此 GitHub 存储库克隆该项目。在此项目中,您将看到以下文件夹结构:

Tokenbasierte Authentifizierung mit Angular und Node

我们拥有三个组件——注册、配置文件和登录——以及一个身份验证服务。

您的app.component.html 如下所示:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
  </head>
  <body>
    <nav class="navbar navbar-expand-lg bg-body-tertiary">
        <div class="container-fluid">
          <a class="navbar-brand" href="#">Home</a>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav">
              
              <li class="nav-item"><a class="nav-link" routerLink="/profile">Me</a></li>
              <li class="nav-item"><a class="nav-link" routerLink="/login">Signin</a></li>
              <li class="nav-item"><a class="nav-link" routerLink="/signup">Signup</a></li>
              <li class="nav-item"><a class="nav-link" (click)="logout()">Logout</a></li>
            </ul>
          </div>
        </div>
      </nav>

    <div class="container">
        <router-outlet></router-outlet>
    </div> 

  </body>
</html>
Nach dem Login kopieren
 

在主组件文件中,<router-outlet></router-outlet> 定义各个组件的路由。

auth.service.ts 文件中,我们定义 AuthService 类,该类通过 API 调用来处理身份验证,以登录、验证 Node.js 应用程序的 API 端点。

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

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  private apiUrl = 'your_node_app_url';
  public token: string ='';


  constructor(private http: HttpClient) {
    
  }


  signin(username: string, password: string): Observable<any> {
    const data = { username, password };
    return this.http.post(`${this.apiUrl}/signin`, data);
  }

 

  authenticate(email: string, password: string): Observable<any> {
    const data = { email, password };
    console.log(data)

    return this.http.post(`${this.apiUrl}/authenticate`, data)
      .pipe(
        tap((response:any) => {
          this.token = response.data.token; // Store the received token
          localStorage.setItem('token',this.token)
          console.log(this.token)
        })
      );
  }

  profile(): Observable<any> {
    const headers = this.createHeaders();
    return this.http.get(`${this.apiUrl}/me`,{ headers });
  }


  private createHeaders(): HttpHeaders {
    let headers = new HttpHeaders({
      'Content-Type': 'application/json',
    });

    if (this.token) {
      headers = headers.append('Authorization', `Bearer ${this.token}`);
    }

    return headers;
  }

  logout(): void {
    
    localStorage.removeItem('token');
  }
 
  
}


Nach dem Login kopieren

authenticate() 方法中,我们向 API 发送 POST 请求并对用户进行身份验证。从响应中,我们提取令牌并将其存储在服务的 this.token 属性和浏览器的 localStorage 中,然后将响应作为 Observable 返回。

profile() 方法中,我们通过在 Authorization 标头中包含令牌来发出 GET 请求以获取用户详细信息。

createHeaders() 方法在发出经过身份验证的 API 请求时创建包含身份验证令牌的 HTTP 标头。当用户拥有有效令牌时,它会添加一个授权标头。该令牌允许后端 API 对用户进行身份验证。

如果身份验证成功,用户令牌将存储在本地存储中以供后续请求使用。该令牌也可供所有组件使用。如果身份验证失败,我们会显示一条错误消息。

不要忘记将服务 URL 放入上面代码中的 baseUrl 中。当您将服务部署到 Heroku 时,您将获得类似 appname.herokuapp.com 的服务 URL。在上面的代码中,您将设置 var baseUrl = "appname.herokuapp.com"

注销功能从本地存储中删除令牌。

signup.component.ts 文件中,我们实现了 signup () 方法,该方法获取用户提交的电子邮件和密码并创建一个新用户。

import { Component } from '@angular/core';
import { AuthService } from '../auth.service';



@Component({
  selector: 'app-signup',
  templateUrl: './signup.component.html',
  styleUrls: ['./signup.component.css']
})
export class SignupComponent {
  password: string = '';
  email: string = '';
  

  constructor(private authService:AuthService){}

  signup(): void {
    this.authService.signin(this.email, this.password).subscribe(
      (response) => {
        // success response
        console.log('Authentication successful', response);
       
      },
      (error) => {
        // error response
        console.error('Authentication error', error);
      }
    );
  }
}
Nach dem Login kopieren
  login.component.ts 文件看起来与注册组件类似。  
import { Component } from '@angular/core';
import { AuthService } from '../auth.service';



@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent {
    
  email: string = '';
  password: string = '';

  constructor(private authService: AuthService) {}

  login(): void {
    this.authService.authenticate(this.email, this.password).subscribe(
      (response) => {
        // success response
        console.log('Signin successful', response);
       
      },
      (error) => {
        // error response
        console.error('Signin error', error);
      }
    );
  }
}
Nach dem Login kopieren

配置文件组件使用用户令牌来获取用户的详细信息。每当您向后端的服务发出请求时,都需要将此令牌放入标头中。 profile.component.ts 如下所示:

import { Component } from '@angular/core';
import { AuthService } from '../auth.service';
@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})

export class ProfileComponent {
  myDetails: any;

  constructor(private authService: AuthService) { }

  ngOnInit(): void {
    this.getProfileData();
  }
  getProfileData(): void {
    this.authService.me().subscribe(
      (response: any) => {
        this.myDetails = response;
        console.log('User Data:', this.myDetails);
      },
      (error: any) => {
        console.error('Error retrieving profile data');
      }
    );
  }
Nach dem Login kopieren
 

在上面的代码中,每个请求都会被拦截,并在标头中放入授权标头和值。然后,我们将用户详细信息传递到 profile.component.html 模板。

<h2>User profile </h2>

<div class="row">
    <div class="col-lg-12">
        <p>{{myDetails.data.id}}</p>
        <p>{{myDetails.data.email}}</p>
    </div>
</div>
Nach dem Login kopieren

最后,我们在 app.routing.module.ts 中定义路由。

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { ProfileComponent } from './profile/profile.component';
import { SignupComponent } from './signup/signup.component';

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

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
Nach dem Login kopieren
 

从上面的代码中您可以很容易地理解,当您转到/时,将呈现app.component.html页面。另一个例子:如果您转到/signup,则会呈现signup.component.html。这个渲染操作将在浏览器中完成,而不是在服务器端。

结论

基于令牌的身份验证系统可帮助您在开发独立于客户端的服务时构建身份验证/授权系统。通过使用这项技术,您将只需专注于您的服务(或 API)。

身份验证/授权部分将由基于令牌的身份验证系统作为服务前面的一层进行处理。您可以从任何客户端(例如网络浏览器、Android、iOS 或桌面客户端)访问和使用服务。

Das obige ist der detaillierte Inhalt vonTokenbasierte Authentifizierung mit Angular und Node. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage