Maison  >  Article  >  interface Web  >  Intégrez l'authentification par empreinte digitale et Face ID dans votre application Angular à l'aide de WebAuthn : un guide étape par étape

Intégrez l'authentification par empreinte digitale et Face ID dans votre application Angular à l'aide de WebAuthn : un guide étape par étape

王林
王林original
2024-09-05 19:00:21790parcourir

Soyons honnêtes : nous avons tous souhaité pouvoir nous connecter à des sites Web en utilisant nos empreintes digitales ou Face ID, tout comme sur les applications mobiles, n'est-ce pas ? Eh bien, grâce à la biométrie Web, ce rêve n’est plus si farfelu. Imaginez abandonner ces mots de passe longs et compliqués et utiliser simplement notre empreinte digitale ou notre visage pour vous connecter à nos sites Web préférés. Ça a l’air cool, n’est-ce pas ?

Integrate Fingerprint and Face ID Authentication in Your Angular App Using WebAuthn: A Step-by-Step Guide

La biométrie Web, optimisée par WebAuthn, rend cela possible. C'est un nom sophistiqué pour quelque chose d'assez simple : nous authentifier avec le même type de sécurité que le capteur d'empreintes digitales ou la reconnaissance faciale de notre téléphone, mais directement dans notre navigateur Web. Ne vous inquiétez plus de la fuite ou du vol de vos mots de passe : il suffit d'une analyse rapide et nous y sommes.

Dans ce didacticiel, nous allons nous familiariser avec l'intégration de la connexion par empreinte digitale et Face ID dans nos applications Angular. Nous aborderons l'essentiel, comme le fonctionnement de l'API WebAuthn et ce que nous devons faire sur le backend pour que tout reste sécurisé et fluide. C’est plus facile que vous ne le pensez, et à la fin, notre application sera prête pour l’avenir de l’authentification. Alors, plongeons-nous et faisons de la connexion un jeu d'enfant !

Comprendre WebAuthn : les bases des empreintes digitales et de la reconnaissance faciale dans les applications angulaires

Integrate Fingerprint and Face ID Authentication in Your Angular App Using WebAuthn: A Step-by-Step Guide

Très bien, avant de passer au code, voyons brièvement ce qu'est WebAuthn. Considérez WebAuthn comme le pont qui connecte nos applications aux fonctionnalités biométriques intéressantes que nous aimons sur nos téléphones, comme les empreintes digitales et Face ID, directement dans nos navigateurs. Il utilise la cryptographie à clé publique pour authentifier les utilisateurs, ce qui signifie qu'il n'est plus nécessaire de stocker d'anciens mots de passe que les pirates peuvent facilement récupérer. Au lieu de cela, nous parlons de clés générées de manière sécurisée qui rendent nos connexions à la fois sûres et transparentes.

Objets clés et leurs rôles

Pour faire avancer les choses, nous devons comprendre quelques acteurs clés du jeu WebAuthn : PublicKeyCredentialCreationOptions et PublicKeyCredentialRequestOptions. Ne vous laissez pas effrayer par les noms longs : ce ne sont que des moyens sophistiqués d'indiquer au navigateur comment nous souhaitons enregistrer et authentifier les utilisateurs.

1. Options de création de clés publiques

Il s'agit de notre objet de prédilection lors de la configuration de nouveaux identifiants utilisateur. Il comprend :

  • défi : une valeur unique et aléatoire générée par le serveur pour garantir que la réponse est fraîche et ne peut pas être réutilisée.
  • rp : signifie Relying Party (notre application) et inclut des détails tels que le nom et l'identifiant de l'application.
  • utilisateur : informations sur l'utilisateur, comme un identifiant unique, un nom d'utilisateur et un nom d'affichage.
  • pubKeyCredParams : une liste d'algorithmes à clé publique que nous autoriserons.
  • authenticatorSelection : nous aide à choisir le bon type d'authentificateur en fonction d'éléments tels que le type de pièce jointe (plateforme ou multiplateforme) et le niveau de vérification de l'utilisateur.

2. Options PublicKeyCredentialRequest

Quand vient le temps de vérifier nos utilisateurs, cet objet prend le devant de la scène. Il comprend :

  • défi : comme avant, cela garantit que notre demande d'authentification est fraîche et unique.
  • allowCredentials : Spécifie les informations d'identification autorisées pour l'utilisateur.
  • userVerification : indique si une vérification de l'utilisateur (comme une analyse d'empreintes digitales) est requise.

Avec ces objets en main, notre application Angular pourra guider les utilisateurs dans l'enregistrement de leurs données biométriques et dans leur authentification rapide et sécurisée. Ensuite, nous entrerons dans le code et verrons comment réaliser cette magie dans notre application !

Configuration de l'application angulaire

Dans cette section, nous vous guiderons dans la configuration d'une application Angular avec authentification biométrique à l'aide de WebAuthn. Nous allons nous concentrer sur l’utilisation des empreintes digitales et de Face ID, alors mettons la main à la pâte !

Étape 1 : Mise en place de notre projet angulaire

Pour commencer, créons un nouveau projet Angular. Ouvrez votre terminal et tapez les commandes suivantes :

ng new web-biometrics-demo
cd web-biometrics-demo
ng serve

Cela configure une application angulaire de base et l'exécution de ng serve démarrera votre application sur http://localhost:4200/. Vous devriez voir la page de bienvenue angulaire par défaut. Nous sommes désormais prêts à intégrer WebAuthn pour l'authentification biométrique.

Étape 2 : Création du service WebAuthn

Nous avons besoin d'un service en Angular pour gérer toutes nos fonctionnalités WebAuthn, y compris l'enregistrement et l'authentification à l'aide de la biométrie. Créons ce service en exécutant :

ng generate service services/webauthn

Now, open webauthn.service.ts and add the following code:

import { Injectable } from '@angular/core';

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

  constructor() { }

  // Generates a random buffer to use as a challenge, which is a unique value needed for security
  private generateRandomBuffer(length: number): Uint8Array {
    const randomBuffer = new Uint8Array(length);
    window.crypto.getRandomValues(randomBuffer); // Fills the buffer with cryptographically secure random values
    return randomBuffer;
  }

  // Registers a new credential (like a fingerprint or Face ID) for the user
  async register() {
    // Generate a unique challenge for the registration process
    const challenge = this.generateRandomBuffer(32);

    // PublicKeyCredentialCreationOptions is the core object needed for registration
    const publicKey: PublicKeyCredentialCreationOptions = {
      challenge: challenge, // A random value generated by the server to ensure the request is fresh and unique
      rp: { // Relying Party (your app) information
        name: "OurAwesomeApp" // Display name of your app
      },
      user: { // User information
        id: this.generateRandomBuffer(16), // A unique identifier for the user
        name: "user@example.com", // User's email or username
        displayName: "User Example" // A friendly name for the user
      },
      pubKeyCredParams: [{ // Array of acceptable public key algorithms
        type: "public-key",
        alg: -7  // Represents the ES256 algorithm (Elliptic Curve Digital Signature Algorithm)
      }],
      authenticatorSelection: { // Criteria for selecting the appropriate authenticator
        authenticatorAttachment: "platform", // Ensures we use the device's built-in biometric authenticator like Touch ID or Face ID
        userVerification: "required" // Requires user verification (e.g., fingerprint or face scan)
      },
      timeout: 60000, // Timeout for the registration operation in milliseconds
      attestation: "direct" // Attestation provides proof of the authenticator's properties and is sent back to the server
    };

    try {
      // This will prompt the user to register their biometric credential
      const credential = await navigator.credentials.create({ publicKey }) as PublicKeyCredential;
      this.storeCredential(credential, challenge); // Store the credential details locally for demo purposes
      console.log("Registration successful!", credential);
      return credential; // Return the credential object containing the user's public key and other details
    } catch (err) {
      console.error("Registration failed:", err);
      throw err; // Handle any errors that occur during registration
    }
  }

  // Authenticates the user with stored credentials (like a fingerprint or Face ID)
  async authenticate() {
    const storedCredential = this.getStoredCredential(); // Retrieve stored credential information
    if (!storedCredential) {
      throw new Error("No stored credential found. Please register first."); // Error if no credentials are found
    }

    // PublicKeyCredentialRequestOptions is used to prompt the user to authenticate
    const publicKey: PublicKeyCredentialRequestOptions = {
      challenge: new Uint8Array(storedCredential.challenge), // A new challenge to ensure the request is fresh and unique
      allowCredentials: [{ // Specifies which credentials can be used for authentication
        id: new Uint8Array(storedCredential.rawId), // The ID of the credential to use
        type: "public-key"
      }],
      userVerification: "required", // Requires user verification (e.g., fingerprint or face scan)
      timeout: 60000 // Timeout for the authentication operation in milliseconds
    };

    try {
      // This will prompt the user to authenticate using their registered biometric credential
      const credential = await navigator.credentials.get({ publicKey }) as PublicKeyCredential;
      console.log("Authentication successful!", credential);
      return credential; // Return the credential object with authentication details
    } catch (err) {
      console.error("Authentication failed:", err);
      throw err; // Handle any errors that occur during authentication
    }
  }

  // Stores credential data in localStorage (for demo purposes only; this should be handled securely in production)
  private storeCredential(credential: PublicKeyCredential, challenge: Uint8Array) {
    const credentialData = {
      rawId: Array.from(new Uint8Array(credential.rawId)), // Converts the raw ID to an array for storage
      challenge: Array.from(challenge) // Converts the challenge to an array for storage
    };
    localStorage.setItem('webauthn_credential', JSON.stringify(credentialData)); // Store the data as a JSON string
  }

  // Retrieves stored credential data from localStorage
  private getStoredCredential(): any {
    const storedCredential = localStorage.getItem('webauthn_credential');
    return storedCredential ? JSON.parse(storedCredential) : null; // Parse the stored JSON back into an object
  }
}

What’s Happening in the Code?

  • generateRandomBuffer: Creates a random buffer that serves as a challenge to ensure each authentication or registration request is unique.

  • register: This method sets up the biometric registration process. It uses PublicKeyCredentialCreationOptions to define parameters like the challenge, relying party (your app), user information, and acceptable public key algorithms. When navigator.credentials.create() is called, the browser prompts the user to register their biometric data.

  • authenticate: This method handles user authentication with biometrics. It uses PublicKeyCredentialRequestOptions to define the authentication challenge and credentials that can be used. The method prompts the user to authenticate with their registered biometrics.

  • storeCredential and getStoredCredential: These methods handle storing and retrieving credentials in localStorage for demonstration purposes.

    In a real-world app, you’d securely store this information on your backend.

Step 3: Building the UI

Now, let’s create a basic UI with buttons to trigger the registration and login functions. This UI will provide feedback based on whether the registration or login was successful.

Open app.component.ts and replace the content with the following:

import { Component } from '@angular/core';
import { WebAuthnService } from './services/webauthn.service';

@Component({
  selector: 'app-root',
  template: `
    <div class="auth-container">
      <h1>Web Biometrics in Angular</h1>
      <button (click)="register()">Register with Fingerprint</button>
      <button (click)="login()">Login with Face ID</button>
      <p *ngIf="message" [ngClass]="{'success': isSuccess, 'error': !isSuccess}">{{ message }}</p>
    </div>
  `,
  styles: [`
    .auth-container {
      text-align: center;
      padding: 50px;
    }
    .success {
      color: green;
    }
    .error {
      color: red;
    }
    button {
      margin: 10px;
      padding: 10px 20px;
      font-size: 16px;
    }
    p {
      margin: 10px;
      font-size: 16px;
    }
  `]
})
export class AppComponent {
  message: string | null = null; // Message to display feedback to the user
  isSuccess: boolean = false; // Indicates if the last action was successful

  constructor(private webAuthnService: WebAuthnService) { }

  // Trigger registration process and update the UI based on the outcome
  async register() {
    try {
      await this.webAuthnService.register();
      this.message = "Registration successful!"; // Success message if registration works
      this.isSuccess = true;
    } catch (err) {
      this.message = "Registration failed. Please try again."; // Error message if something goes wrong
      this.isSuccess = false;
    }
  }

  // Trigger authentication process and update the UI based on the outcome
  async login() {
    try {
      await this.webAuthnService.authenticate();
      this.message = "Authentication successful!"; // Success message if authentication works
      this.isSuccess = true;
    } catch (err) {
      this.message = "Authentication failed. Please try again."; // Error message if something goes wrong
      this.isSuccess = false;
    }
  }
}

What’s Happening in the Component?

register and login methods: These methods call the respective register and authenticate methods from the WebAuthnService. If successful, a success message is displayed; otherwise, an error message is shown.

Template and Styling: The template includes buttons to trigger registration and login, and it displays messages to the user based on the operation's outcome. The buttons are styled for simplicity.

That’s it! We’ve built a basic Angular app with WebAuthn-based biometric authentication, supporting fingerprints and Face ID. This setup captures the core concepts and lays a foundation that can be expanded with additional features and security measures for a production environment.

Backend Considerations

When implementing biometric authentication like fingerprints or Face ID in web applications using WebAuthn, the backend plays a crucial role in managing the security and flow of data. Here’s a breakdown of how the backend processes work in theory, focusing on registration and login functionalities.

Registration: Sign-up

1. User Registration Flow:

  • User Data Capture: During registration, the user provides basic credentials, such as an email and password. If biometric data is also being registered, this is captured as part of the WebAuthn response.

  • Password Hashing: For security, passwords are never stored in plain text. Instead, they are hashed using a library like bcrypt before being stored in the database.

  • Storing WebAuthn Credentials:

    • Challenge Handling: The server sends a challenge during the registration process, which is a randomly generated value to prevent replay attacks.
    • Response Validation: When the client responds with the WebAuthn data, it includes clientDataJSON and attestationObject that need to be decoded and verified.
    • Credential Storage: After validation, key data from the response—like the webauthnId (a unique identifier for the credential) and the publicKey (used to verify future authentications)—are stored in the database alongside the user record.

2. Backend Code Responsibilities:

  • The backend uses libraries like cbor to decode binary data formats from the WebAuthn response, extracting necessary elements like the public key and authenticator data.

  • It ensures that the challenge from the initial registration request matches what is returned in the WebAuthn response to verify the authenticity of the registration.

  • If the WebAuthn response passes all checks, the credentials are saved in the database, linked to the user account.

Login

1. User Login Flow:

  • Challenge Generation: Similar to registration, the server generates a challenge that must be responded to by the client’s authenticator during login.

  • Validating the WebAuthn Response:

    • Der Client sendet ein PublicKeyCredentialRequestOptions-Objekt zurück, das die Antwort auf die Herausforderung enthält.
    • Das Backend dekodiert und überprüft diese Antwort und stellt so sicher, dass die Herausforderung und die Anmeldeinformationen mit dem übereinstimmen, was in der Datenbank gespeichert ist.
  • Berechtigungsüberprüfung:

    • Der bei der Registrierung gespeicherte öffentliche Schlüssel wird zur Überprüfung der Signatur in der Anmeldeantwort verwendet.
    • Wenn die Anmeldeinformationen übereinstimmen, lässt das Backend die Anmeldung zu und generiert ein Authentifizierungstoken (wie ein JWT) für die Sitzung.

Fehlerbehandlung:

  • Nichtübereinstimmung oder ungültige Antwort: Wenn die Challenge-Antwort nicht mit den erwarteten Werten übereinstimmt oder wenn die WebAuthn-Anmeldeinformationen nicht korrekt überprüft werden, antwortet das Backend mit einem Fehler und verhindert so unbefugten Zugriff.

  • Fallback auf Passwort: Wenn WebAuthn fehlschlägt oder nicht verfügbar ist, kann das System zur herkömmlichen Passwortüberprüfung zurückkehren und sicherstellen, dass Benutzer weiterhin auf ihre Konten zugreifen können.

Sicherheitsüberlegungen

  • Datenintegrität: Die Integrität der WebAuthn-Anmeldeinformationen ist von entscheidender Bedeutung. Jede Änderung bei der Speicherung oder Übertragung würde dazu führen, dass die Überprüfung fehlschlägt, wodurch der Authentifizierungsprozess gesichert wird.

  • Challenge Nonces: Die Verwendung einzigartiger, zeitlich begrenzter Challenges stellt sicher, dass Antworten nicht wiederverwendet werden können, und schützt so vor Replay-Angriffen.

  • Öffentliche Schlüsselspeicherung: Die ausschließliche Speicherung öffentlicher Schlüssel (die nicht dazu verwendet werden können, sich als Benutzer auszugeben) erhöht die Sicherheit, da private Schlüssel auf dem Clientgerät verbleiben.

Durch die Befolgung dieser Prinzipien verwaltet das Backend die biometrische Authentifizierung effektiv und sorgt so für ein sicheres, nahtloses Erlebnis für Benutzer, die Funktionen wie Fingerabdruck oder Face ID in ihren Angular-Apps verwenden möchten.

Zusammenfassend

In diesem Tutorial haben wir uns mit der Integration der biometrischen Authentifizierung in Angular mithilfe von WebAuthn befasst. Wir haben das Wesentliche behandelt, vom Verständnis wichtiger WebAuthn-Objekte wie PublicKeyCredentialCreationOptions und PublicKeyCredentialRequestOptions bis hin zum Einrichten von Angular-Diensten und UI-Komponenten für einen reibungslosen Registrierungs- und Anmeldeprozess. Wir haben auch die Backend-Überlegungen besprochen, die für die sichere Handhabung der biometrischen Authentifizierung erforderlich sind.

Für diejenigen, die WebAuthn unbedingt in Aktion sehen möchten, habe ich eine Demo und ein Repository mit einer vollständigen Implementierung bereitgestellt. Sie können sich die Demo hier ansehen und den Quellcode auf GitHub in diesem Repository erkunden.

Die Einführung der biometrischen Authentifizierung erhöht nicht nur die Sicherheit, sondern vereinfacht auch das Benutzererlebnis und ebnet den Weg für eine Zukunft, in der die Anmeldung so einfach ist wie ein Fingerabdruck-Scan oder eine schnelle Gesichtserkennung. Wenn Sie diese Funktionen in Ihre Angular-Apps integrieren, tragen Sie zu einem sichereren und benutzerfreundlicheren Web bei. Viel Spaß beim Codieren!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:FonctionsArticle suivant:Fonctions