Skip to content

تسجيل الدخول بدون كلمة مرور عبر WebAuthn

ينفّذ Doggy مصادقة WebAuthn القياسية استنادًا إلى web-auth/webauthn-symfony-bundle، ويدعم تسجيل الدخول عبر بصمة الإصبع والتعرف على الوجه والمفاتيح الأمنية.

نظرة عامة

تُخزَّن بيانات اعتماد WebAuthn في src/Entity/Security/WebauthnCredential.php (جدول webauthn_credentials)، وترتبط بـ App\Entity\Organization\Employee (كيان المستخدم).

ينفّذ مستودع بيانات الاعتماد واجهة PublicKeyCredentialSourceRepositoryInterface، ويدعم حفظ واستعلام بيانات اعتماد WebAuthn.

التكوين

yaml
# config/packages/webauthn.yaml
webauthn:
  credential_repository: 'App\Repository\Security\WebauthnCredentialRepository'
  user_repository: 'App\Repository\Organization\EmployeeRepository'
  creation_profiles:
    default:
      rp:
        name: '%env(RELYING_PARTY_NAME)%'
        id: '%env(RELYING_PARTY_ID)%'
      public_key_credential_parameters:
        - -7    # ES256
        - -257  # RS256
      authenticator_selection_criteria:
        resident_key: required
        user_verification: required
  request_profiles:
    default:
      rp_id: '%env(RELYING_PARTY_ID)%'
      user_verification: required
  allowed_origins: ['http://localhost:8000']

تكوين جدار الحماية الأمني

yaml
# config/packages/security.yaml
security:
  firewalls:
    main:
      custom_authenticator: App\Security\AppCustomAuthenticator
      webauthn:
        success_handler: App\Security\WebauthnSuccessHandler
        authentication:
          enabled: true
          routes:
            options_path: '/login/webauthn/options'
            result_path: '/login/webauthn/result'

إدارة بيانات الاعتماد

php
// src/Entity/Security/WebauthnCredential.php
class WebauthnCredential
{
    private string $publicKeyCredentialId;
    private string $type;          // 'public-key'
    private array $transports;     // ['usb', 'nfc', 'internal']
    private string $attestationType;
    private string $credentialPublicKey;
    private string $userHandle;    // Employee ID
    private int $counter;
    private ?string $deviceName;   // 如 "Chrome on Mac"

    #[ORM\ManyToOne(targetEntity: Employee::class, inversedBy: 'passkeys')]
    private ?Employee $employee = null;
}

مسار تسجيل الدخول

تسجيل Passkey

  1. بعد تسجيل دخول المستخدم يدخل إلى إعدادات الأمان (/user/webauthn/register/options)
  2. يستدعي المتصفح واجهة WebAuthn API لإنشاء بيانات الاعتماد
  3. تُرسل النتيجة إلى /user/webauthn/register/result
  4. تُخزَّن بيانات الاعتماد العامة في جدول webauthn_credentials

تسجيل الدخول بدون كلمة مرور

  1. أدخل اسم المستخدم ثم انقر "تسجيل دخول Passkey"
  2. أرسل POST إلى /login/webauthn/options للحصول على التحدي (challenge)
  3. يستدعي المتصفح واجهة WebAuthn API للتوقيع
  4. تُرسل النتيجة إلى /login/webauthn/result
  5. يعالج WebauthnSuccessHandler نجاح تسجيل الدخول (تسجيل الجهاز، تحديث الوقت)

معالج النجاح

يقوم App\Security\WebauthnSuccessHandler بعد نجاح تسجيل الدخول بـ:

  1. تحديث وقت آخر استخدام لبيانات الاعتماد
  2. التعرف التلقائي على اسم الجهاز (تحليل User-Agent)
  3. التحقق مما إذا كان هذا أول تسجيل دخول وتوجيه المستخدم لتغيير كلمة المرور
  4. دعم مسار إعادة تعيين كلمة المرور

مستودع بيانات اعتماد WebAuthn

ينفّذ App\Repository\Security\WebauthnCredentialRepository:

  • findOneByCredentialId(): البحث عن بيانات الاعتماد
  • findAllForUserEntity(): الحصول على جميع بيانات اعتماد المستخدم
  • saveCredentialSource(): إنشاء/تحديث بيانات الاعتماد
  • parseUserAgent(): التعرف على اسم الجهاز

مصدر مفتوح برخصة MIT | حقوق النشر © 2026 Doggy