با یک رمز عبور وارد شوید

این راهنما در ادامه به پیاده‌سازی استفاده از کلیدهای عبور برای احراز هویت می‌پردازد. قبل از اینکه کاربران شما بتوانند با کلیدهای عبور وارد سیستم شوند، باید دستورالعمل‌های موجود در بخش «ایجاد کلیدهای عبور» را نیز تکمیل کنید.

برای احراز هویت با کلید عبور، ابتدا باید گزینه‌های مورد نیاز برای بازیابی کلید عمومی را از سرور برنامه خود بازیابی کنید و سپس API مدیریت اعتبار را برای بازیابی کلید عمومی فراخوانی کنید. سپس، پاسخ ورود به سیستم را به طور مناسب مدیریت کنید.

نمای کلی

این راهنما بر تغییرات مورد نیاز در برنامه کلاینت شما برای ورود کاربر با کلید عبور تمرکز دارد و خلاصه‌ای از پیاده‌سازی سمت سرور برنامه را ارائه می‌دهد. برای کسب اطلاعات بیشتر در مورد ادغام سمت سرور، به احراز هویت سمت سرور مراجعه کنید.

برای بازیابی تمام گزینه‌های رمز عبور و کلید عبور مرتبط با حساب کاربری، این مراحل را انجام دهید:

  1. دریافت گزینه‌های درخواست اعتبارنامه از سرور : درخواستی از برنامه خود به سرور احراز هویت خود ارسال کنید تا فرآیند ورود با کلید عبور آغاز شود. از سرور، گزینه‌های مورد نیاز برای دریافت کلید عمومی اعتبارنامه و همچنین یک چالش منحصر به فرد را ارسال کنید.
  2. شیء مورد نیاز برای دریافت اعتبارنامه کلید عمومی را ایجاد کنید : گزینه‌های ارسال شده توسط سرور را در یک شیء GetPublicKeyCredentialOption قرار دهید.
  3. ( اختیاری) Prepare getCredential : در اندروید ۱۴ و بالاتر، می‌توانید با نمایش انتخابگر حساب کاربری با استفاده از متد prepareGetCredential() قبل از فراخوانی getCredential() تأخیر را کاهش دهید.
  4. جریان ورود به سیستم را راه‌اندازی کنید : برای ورود کاربر، متد getCredential() را فراخوانی کنید.
  5. مدیریت پاسخ : مدیریت هر یک از پاسخ‌های ممکن به اعتبارنامه‌ها.
  6. مدیریت استثنائات : مطمئن شوید که استثنائات را به طور مناسب مدیریت می‌کنید.

۱. گزینه‌های درخواست اعتبارنامه را از سرور دریافت کنید

از سرور گزینه‌های مورد نیاز برای دریافت اعتبارنامه‌های کلید عمومی و همچنین challenge را که برای هر تلاش ورود منحصر به فرد است، درخواست کنید. برای کسب اطلاعات بیشتر در مورد پیاده‌سازی سمت سرور، به گزینه‌های ایجاد چالش و ایجاد درخواست اعتبارنامه مراجعه کنید.

گزینه‌ها شبیه به موارد زیر هستند:

{
  "challenge": "<your app challenge>",
  "allowCredentials": [],
  "rpId": "<your app server domain>"
}

برای کسب اطلاعات بیشتر در مورد فیلدها، به پست وبلاگ در مورد ورود با رمز عبور مراجعه کنید.

۲. شیء مورد نیاز برای دریافت اعتبارنامه کلید عمومی را ایجاد کنید

در برنامه خود، از گزینه‌ها برای ایجاد یک شیء GetPublicKeyCredentialOption استفاده کنید. در مثال زیر، requestJson نشان‌دهنده گزینه‌های ارسال شده توسط سرور است.

// Get password logins from the credential provider on the user's device.
val getPasswordOption = GetPasswordOption()

// Get passkeys from the credential provider on the user's device.
val getPublicKeyCredentialOption = GetPublicKeyCredentialOption(
    requestJson = requestJson
)

سپس، GetPublicKeyCredentialOption در یک شیء GetCredentialRequest قرار دهید.

val credentialRequest = GetCredentialRequest(
    // Include all the sign-in options that your app supports.
    listOf(getPasswordOption, getPublicKeyCredentialOption),
    // Defines whether you prefer to use only immediately available
    // credentials or hybrid credentials.
    preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials
)

۳. اختیاری: کاهش تأخیر ورود به سیستم

در اندروید ۱۴ یا بالاتر، می‌توانید با استفاده از متد prepareGetCredential() قبل از فراخوانی getCredential() ، تأخیر هنگام نمایش انتخابگر حساب را کاهش دهید.

متد prepareGetCredential() یک شیء PrepareGetCredentialResponse را که ذخیره شده است، برمی‌گرداند. این به متد getCredential() اجازه می‌دهد تا در مرحله بعد، انتخابگر حساب را با داده‌های ذخیره شده نمایش دهد.

coroutineScope {
    val response = credentialManager.prepareGetCredential(
        GetCredentialRequest(
            listOf(
                // Include all the sign-in options that your app supports
                getPublicKeyCredentialOption, 
                getPasswordOption
            )
        )
    )
}

۴. جریان ورود به سیستم را راه‌اندازی کنید

متد getCredential() را فراخوانی کنید تا انتخابگر حساب کاربری را به کاربر نشان دهید. از قطعه کد زیر به عنوان مرجعی برای نحوه‌ی راه‌اندازی جریان ورود به سیستم استفاده کنید:

coroutineScope {
    try {
        result = credentialManager.getCredential(
            // Use an activity-based context to avoid undefined system UI
            // launching behavior.
            context = activityContext,
            request = credentialRequest
        )
        handleSignIn(result)
    } catch (e: GetCredentialException) {
        // Handle failure
    }
}

۵. پاسخ را مدیریت کنید

پاسخ را مدیریت کنید، که می‌تواند شامل یکی از انواع مختلف اشیاء اعتبارنامه باشد.

fun handleSignIn(result: GetCredentialResponse) {
    // Handle the successfully returned credential.
    val credential = result.credential

    when (credential) {
        is PublicKeyCredential -> {
            val responseJson = credential.authenticationResponseJson
            // Share responseJson i.e. a GetCredentialResponse on your server to
            // validate and  authenticate
        }

        is PasswordCredential -> {
            val username = credential.id
            val password = credential.password
            // Use id and password to send to your server to validate
            // and authenticate
        }

        is CustomCredential -> {
            // If you are also using any external sign-in libraries, parse them
            // here with the utility functions provided.
            if (credential.type == ExampleCustomCredential.TYPE) {
                try {
                    val ExampleCustomCredential =
                        ExampleCustomCredential.createFrom(credential.data)
                    // Extract the required credentials and complete the authentication as per
                    // the federated sign in or any external sign in library flow
                } catch (e: ExampleCustomCredential.ExampleCustomCredentialParsingException) {
                    // Unlikely to happen. If it does, you likely need to update the dependency
                    // version of your external sign-in library.
                    Log.e(TAG, "Failed to parse an ExampleCustomCredential", e)
                }
            } else {
                // Catch any unrecognized custom credential type here.
                Log.e(TAG, "Unexpected type of credential")
            }
        }
        else -> {
            // Catch any unrecognized credential type here.
            Log.e(TAG, "Unexpected type of credential")
        }
    }
}

PublicKeyCredential برگردانده شده از احراز هویت اساساً یک ادعای امضا شده است که به شرح زیر ساختار یافته است:

{
  "id": "<credential ID>",
  "type": "public-key",
  "rawId": "<raw credential ID>",
  "response": {
    "clientDataJSON": "<signed client data containing challenge>",
    "authenticatorData": "<authenticator metadata>",
    "signature": "<digital signature to be verified>",
    "userHandle": "<user ID from credential registration>"
  }
}

در سرور، باید اعتبارنامه را تأیید کنید. برای کسب اطلاعات بیشتر، به بخش «تأیید و ورود کاربر» مراجعه کنید.

۶. مدیریت استثنائات

شما باید تمام استثنائات زیرکلاس GetCredentialException را مدیریت کنید. برای یادگیری نحوه مدیریت هر استثنا، به راهنمای عیب‌یابی مراجعه کنید.

coroutineScope {
    try {
        result = credentialManager.getCredential(
            context = activityContext,
            request = credentialRequest
        )
    } catch (e: GetCredentialException) {
        Log.e("CredentialManager", "No credential available", e)
    }
}

مراحل بعدی