WebAuthn を使用して Angular アプリに指紋認証と Face ID 認証を統合する: ステップバイステップ ガイド

王林
リリース: 2024-09-05 19:00:21
オリジナル
807 人が閲覧しました

正直に言うと、モバイル アプリと同じように、指紋や Face ID を使用して Web サイトにログインできればと誰もが思ったことがあるでしょう?ウェブ生体認証のおかげで、その夢はそれほど遠い夢ではなくなりました。長くて複雑なパスワードを捨てて、指紋や顔を使ってお気に入りの Web サイトにサインインすることを想像してみてください。素敵ですね?

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

WebAuthn を活用した Web 生体認証により、これが可能になります。これは非常に単純なものに対する派手な名前です。携帯電話の指紋センサーや顔認識と同じ種類のセキュリティを使用して、Web ブラウザーで直接認証することです。パスワードが漏洩したり盗まれたりする心配はもうありません。簡単にスキャンするだけで大​​丈夫です。

このチュートリアルでは、指紋と Face ID ログインを Angular アプリに統合する方法を実践していきます。 WebAuthn API がどのように機能するか、すべてを安全かつスムーズに保つためにバックエンドで何をする必要があるかなど、基本的な事項について説明します。それはあなたが思っているよりも簡単で、最終的には、将来の認証に向けてアプリをすべてセットアップすることができます。それでは、早速ログインを簡単にしてみましょう!

WebAuthn について: Angular アプリにおける指紋と顔認識の基礎

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

それでは、コードの説明に入る前に、WebAuthn とは何なのかを簡単に理解しましょう。 WebAuthn は、指紋や Face ID など、携帯電話で愛用されているクールな生体認証機能とアプリをブラウザ内で直接接続するブリッジと考えてください。公開キー暗号化を使用してユーザーを認証するため、ハッカーが簡単に入手できる古いパスワードを保存する必要がなくなります。代わりに、ログインを安全かつシームレスにする、安全に生成されたキーについて話しています。

主要なオブジェクトとその役割

物事を進めるには、WebAuthn ゲームのいくつかの主要なプレーヤーである PublicKeyCredentialCreationOptions と PublicKeyCredentialRequestOptions を理解する必要があります。長い名前を見て怖がらないでください。それらは、ユーザーの登録と認証の方法をブラウザーに伝えるための派手な方法にすぎません。

1. PublicKeyCredentialCreationOptions

これは、新しいユーザー資格情報を設定するときに頼りになるオブジェクトです。これには以下が含まれます:

  • チャレンジ: 応答が最新で再利用できないことを保証するためにサーバーによって生成される一意のランダムな値。
  • rp: Relying Party (アプリ) の略で、アプリの名前や ID などの詳細が含まれます。
  • user: 一意の ID、ユーザー名、表示名などのユーザーに関する情報。
  • pubKeyCredParams: 許可される公開鍵アルゴリズムのリスト。
  • authenticatorSelection: 添付ファイルのタイプ (プラットフォームまたはクロスプラットフォーム) やユーザー検証レベルなどに基づいて、適切なタイプの認証システムを選択するのに役立ちます。

2. PublicKeyCredentialRequestOptions

ユーザーを認証するときは、このオブジェクトが注目を集めます。これには以下が含まれます:

  • チャレンジ: 以前と同様に、これにより認証リクエストが新鮮かつ一意であることが保証されます。
  • allowCredentials: ユーザーに許可される資格情報を指定します。
  • userVerification: ユーザー検証 (指紋スキャンなど) が必要かどうかを指定します。

これらのオブジェクトを使用すると、Angular アプリはユーザーをガイドして、生体データの登録と認証を迅速かつ安全に行うことができます。次に、コードを見て、アプリでこの魔法を実現する方法を見てみましょう!

Angular アプリのセットアップ

このセクションでは、WebAuthn を使用した生体認証を備えた Angular アプリケーションのセットアップについて説明します。指紋と Face ID の使用に焦点を当てますので、実際に試してみましょう!

ステップ 1: Angular プロジェクトをセットアップする

まず、新しい Angular プロジェクトを作成しましょう。ターミナルを開き、次のコマンドを入力します:

ng new web-biometrics-demo
cd web-biometrics-demo
ng serve
ログイン後にコピー

これにより、基本的な Angular アプリケーションがセットアップされ、ngserve を実行すると、http://localhost:4200/ でアプリが起動されます。デフォルトの Angular のようこそページが表示されるはずです。これで、生体認証に WebAuthn を統合する準備が整いました。

ステップ 2: WebAuthn サービスの作成

生体認証を使用した登録や認証など、すべての WebAuthn 機能を管理するには、Angular のサービスが必要です。次を実行してこのサービスを作成しましょう:

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:

    • 客户端发回一个包含对质询的响应的 PublicKeyCredentialRequestOptions 对象。
    • 后端解码并验证此响应,确保质询和凭据与数据库中存储的内容匹配。
  • 凭证验证:

    • 注册期间存储的公钥用于验证登录响应中的签名。
    • 如果凭据匹配,后端将允许登录并为会话生成身份验证令牌(如 JWT)。

错误处理:

  • 不匹配或无效响应:如果质询响应与预期值不匹配,或者 WebAuthn 凭据未正确验证,后端会返回错误,以防止未经授权的访问。

  • 回退到密码:如果 WebAuthn 失败或不可用,系统可以恢复到传统的密码验证,确保用户仍然可以访问其帐户。

安全考虑

  • 数据完整性:WebAuthn 凭据的完整性至关重要。存储或传输中的任何修改都会导致验证失败,从而确保身份验证过程的安全。

  • 挑战随机数:使用独特的、有时间限制的挑战可确保响应无法重复使用,从而防止重放攻击。

  • 公钥存储:仅存储公钥(不能用于模拟用户)可以增强安全性,因为私钥保留在客户端设备上。

通过遵循这些原则,后端可以有效地管理生物识别身份验证,确保为想要在 Angular 应用中使用指纹或 Face ID 等功能的用户提供安全、无缝的体验。

总之

在本教程中,我们介绍了使用 WebAuthn 将生物识别身份验证与 Angular 集成。我们涵盖了基础知识,从理解关键的 WebAuthn 对象(如 PublicKeyCredentialCreationOptions 和 PublicKeyCredentialRequestOptions)到设置 Angular 服务和 UI 组件以实现顺利的注册和登录过程。我们还讨论了安全处理生物识别身份验证所需的后端注意事项。

对于那些渴望看到 WebAuthn 实际应用的人,我提供了一个演示和一个具有完整实现的存储库。您可以在此处查看演示,并在 GitHub 上的此存储库中探索源代码。

采用生物识别身份验证不仅可以增强安全性,还可以简化用户体验,为未来像指纹扫描或快速面部识别一样轻松的登录铺平道路。当您将这些功能集成到 Angular 应用程序中时,您将为构建更安全、更用户友好的网络做出贡献。快乐编码!

以上がWebAuthn を使用して Angular アプリに指紋認証と Face ID 認証を統合する: ステップバイステップ ガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート