Seien wir ehrlich – wir alle haben uns doch gewünscht, dass wir uns mit unseren Fingerabdrücken oder Face ID auf Websites anmelden könnten, genau wie bei mobilen Apps, oder? Nun, dank der Webbiometrie ist dieser Traum nicht mehr so weit hergeholt. Stellen Sie sich vor, Sie würden auf lange, komplizierte Passwörter verzichten und sich einfach mit unserem Fingerabdruck oder Ihrem Gesicht auf unseren Lieblingswebsites anmelden. Klingt cool, nicht wahr?
Webbiometrie, unterstützt von WebAuthn, macht dies möglich. Es ist ein schicker Name für etwas ganz Einfaches: die Authentifizierung mit der gleichen Sicherheit wie der Fingerabdrucksensor oder die Gesichtserkennung unseres Telefons, aber direkt in unserem Webbrowser. Machen Sie sich keine Sorgen mehr, dass Passwörter durchsickern oder gestohlen werden – nur ein kurzer Scan und schon sind wir dabei.
In diesem Tutorial werden wir die Integration der Fingerabdruck- und Face-ID-Anmeldung in unsere Angular-Apps praktisch erlernen. Wir behandeln das Wesentliche, etwa die Funktionsweise der WebAuthn-API und was wir im Backend tun müssen, um alles sicher und reibungslos zu halten. Es ist einfacher, als Sie vielleicht denken, und am Ende haben wir unsere App für die Zukunft der Authentifizierung gerüstet. Also, lasst uns eintauchen und die Anmeldung zum Kinderspiel machen!
Okay, bevor wir uns mit dem Code befassen, werfen wir einen kurzen Blick darauf, worum es bei WebAuthn geht. Stellen Sie sich WebAuthn als die Brücke vor, die unsere Apps direkt in unseren Browsern mit den coolen biometrischen Funktionen verbindet, die wir auf unseren Telefonen lieben – wie Fingerabdrücke und Face ID. Es verwendet Public-Key-Kryptografie zur Authentifizierung von Benutzern, was bedeutet, dass keine einfachen alten Passwörter mehr gespeichert werden müssen, die Hacker leicht erbeuten könnten. Stattdessen sprechen wir von sicher generierten Schlüsseln, die unsere Anmeldungen sowohl sicher als auch nahtlos machen.
Um die Dinge ins Rollen zu bringen, müssen wir einige Schlüsselakteure im WebAuthn-Spiel verstehen: PublicKeyCredentialCreationOptions und PublicKeyCredentialRequestOptions. Lassen Sie sich von den langen Namen nicht abschrecken – es handelt sich lediglich um ausgefallene Möglichkeiten, dem Browser mitzuteilen, wie wir Benutzer registrieren und authentifizieren möchten.
Dies ist unser Ziel beim Einrichten neuer Benutzeranmeldeinformationen. Es beinhaltet:
Wenn es an der Zeit ist, unsere Benutzer zu verifizieren, rückt dieses Objekt ins Rampenlicht. Es beinhaltet:
Mit diesen Objekten in der Hand kann unsere Angular-App Benutzer durch die Registrierung ihrer biometrischen Daten und die schnelle und sichere Authentifizierung führen. Als nächstes beschäftigen wir uns mit dem Code und sehen, wie wir diese Magie in unserer App verwirklichen können!
In diesem Abschnitt führen wir Sie durch die Einrichtung einer Angular-Anwendung mit biometrischer Authentifizierung mithilfe von WebAuthn. Wir werden uns auf die Verwendung von Fingerabdrücken und Face ID konzentrieren, also machen wir uns die Hände schmutzig!
Um zu beginnen, erstellen wir ein neues Angular-Projekt. Öffnen Sie Ihr Terminal und geben Sie die folgenden Befehle ein:
ng new web-biometrics-demo cd web-biometrics-demo ng serve
Dadurch wird eine grundlegende Angular-Anwendung eingerichtet und durch Ausführen von ng Serve wird Ihre App unter http://localhost:4200/ gestartet. Sie sollten die standardmäßige Angular-Willkommensseite sehen. Jetzt sind wir bereit, WebAuthn für die biometrische Authentifizierung zu integrieren.
Wir benötigen einen Dienst in Angular, um alle unsere WebAuthn-Funktionen zu verwalten, einschließlich der Registrierung und Authentifizierung mithilfe biometrischer Daten. Lassen Sie uns diesen Dienst erstellen, indem wir Folgendes ausführen:
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 } }
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.
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; } } }
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.
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.
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:
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.
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:
憑證驗證:
不匹配或無效回應:如果質詢回應與預期值不匹配,或 WebAuthn 憑證未正確驗證,後端會傳回錯誤,以防止未經授權的存取。
回退到密碼:如果 WebAuthn 失敗或不可用,系統可以恢復到傳統的密碼驗證,確保使用者仍然可以存取其帳戶。
資料完整性:WebAuthn 憑證的完整性至關重要。儲存或傳輸中的任何修改都會導致驗證失敗,從而確保身份驗證過程的安全。
挑戰隨機數:使用獨特的、有時間限制的挑戰可確保回應無法重複使用,從而防止重播攻擊。
公鑰儲存:僅儲存公鑰(不能用於類比使用者)可以增強安全性,因為私鑰保留在客戶端裝置上。
透過遵循這些原則,後端可以有效管理生物辨識身分驗證,確保為想要在 Angular 應用中使用指紋或 Face ID 等功能的使用者提供安全、無縫的體驗。
在本教程中,我們介紹了使用 WebAuthn 將生物辨識身份驗證與 Angular 整合。我們涵蓋了基礎知識,從理解關鍵的 WebAuthn 物件(如 PublicKeyCredentialCreationOptions 和 PublicKeyCredentialRequestOptions)到設定 Angular 服務和 UI 元件以實現順利的註冊和登入流程。我們也討論了安全處理生物辨識身分驗證所需的後端注意事項。
對於那些渴望看到 WebAuthn 實際應用的人,我提供了一個演示和一個具有完整實現的存儲庫。您可以在此處查看演示,並在 GitHub 上的此儲存庫中探索原始程式碼。
採用生物辨識身分驗證不僅可以增強安全性,還可以簡化使用者體驗,為未來像指紋掃描或快速臉部辨識一樣輕鬆的登入鋪平道路。當您將這些功能整合到 Angular 應用程式中時,您將為建立更安全、更用戶友好的網路做出貢獻。快樂編碼!
Das obige ist der detaillierte Inhalt vonIntegrieren Sie die Fingerabdruck- und Face-ID-Authentifizierung in Ihre Angular-App mit WebAuthn: Eine Schritt-für-Schritt-Anleitung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!