پیاده‌سازی «بازگرداندن اعتبارنامه‌ها» با Credential Manager

این صفحه نحوه ایجاد، ورود به سیستم، و حذف کلید بازیابی را شرح می‌دهد.

سازگاری نسخه

«بازگرداندن اعتبارنامه‌ها» در Credential Manager در دستگاه‌های دارای Android 9 (سطح میانای برنامه‌سازی کاربردی ۲۸) و بالاتر، نسخه اصلی ۲۴۲۲۰۰۰۰ یا بالاتر «خدمات Google Play» (GMS)، و نسخه ۱.۵.۰ یا بالاتر کتابخانه androidx.credentials کار می‌کند.

پیش‌نیازها

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

وابستگی‌ها

وابستگی‌های زیر را به فایل build.gradle واحد برنامه‌تان اضافه کنید:

کاتلین

dependencies {
    implementation("androidx.credentials:credentials:1.7.0-alpha03")
    implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha03")
}

شیار

dependencies {
    implementation "androidx.credentials:credentials:1.7.0-alpha03"
    implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha03"
}

«بازگرداندن اعتبارنامه‌ها» از نسخه ۱.۵.۰ و بالاتر کتابخانه androidx.credentials دردسترس است. بااین‌حال، توصیه می‌شود درصورت امکان از جدیدترین نسخه‌های پایدار وابستگی‌ها استفاده کنید.

نمای کلی

  1. ایجاد کلید بازیابی: برای ایجاد کلید بازیابی، مراحل زیر را تکمیل کنید:
    1. نمونه‌سازی Credential Manager: یک شیء CredentialManager ایجاد کنید.
    2. دریافت گزینه‌های ایجاد اعتبارنامه از سرور برنامه: جزئیات لازم برای ایجاد کلید بازیابی را از سرور برنامه به برنامه کارخواه ارسال کنید.
    3. ایجاد کلید بازیابی: اگر کاربر به سیستم برنامه‌تان وارد شده است، کلید بازیابی برای حساب کاربر ایجاد کنید.
    4. رسیدگی به پاسخ ایجاد اعتبارنامه: اعتبارنامه را از برنامه مشتری به سرور برنامه ارسال کنید تا پردازش شود و به هرگونه استثنا رسیدگی کنید.
  2. ورود به سیستم با کلید بازیابی: برای ورود به سیستم با کلید بازیابی، مراحل زیر را تکمیل کنید:
    1. دریافت گزینه‌های بازیابی اعتبارنامه از سرور برنامه: جزئیات لازم برای بازیابی کلید بازیابی از سرور برنامه را به برنامه کارخواه ارسال کنید.
    2. دریافت کلید بازیابی: وقتی کاربر دستگاه جدیدی راه‌اندازی می‌کند، کلید بازیابی را از Credential Manager درخواست کنید. این کار به کاربر اجازه می‌دهد بدون ورودی اضافی به سیستم وارد شود.
    3. مدیریت پاسخ بازیابی اطلاعات کاربری: کلید بازیابی را از برنامه کارخواه به سرور برنامه ارسال کنید تا کاربر به سیستم وارد شود.
  3. حذف کلید بازیابی.

ایجاد کلید بازیابی

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

  • اگر کاربر به سیستم وارد شده باشد و کلید بازیابی ازقبل ایجاد نشده باشد (مثلاً در روش onCreate برای Activity اصلی).
  • وقتی کاربر درحال ورود به سیستم یا تکمیل جریان ثبت‌نام حساب جدید است.

برای بهینه‌سازی عملکرد و اجتناب از سربار ایجاد یا بررسی اعتبارنامه بازیابی در هر ورود به سیستم، پرچم boolean یا مُهر زمان ایجاد اعتبارنامه را در فضای ذخیره‌سازی محلی، مانند has_synced_restore_credential، تنظیم کنید تا ردیابی شود که آیا کلید قبلاً ایجاد شده است یا نه.

نمونه‌سازی Credential Manager

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

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)

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

از کتابخانه سازگار با FIDO در سرور برنامه‌تان استفاده کنید تا اطلاعات لازم برای ایجاد اعتبارنامه بازیابی را به برنامه کارخواه ارسال کنید، مثلاً اطلاعات مربوط به کاربر، برنامه، و ویژگی‌های پیکربندی اضافی. برای اطلاعات بیشتر درباره پیاده‌سازی سمت سرور، به راهنمای سمت سرور مراجعه کنید.

ایجاد کلید بازیابی

پس‌از تجزیه کردن گزینه‌های ایجاد کلید عمومی ارسال‌شده توسط سرور، با قرار دادن این گزینه‌ها در شیء CreateRestoreCredentialRequest و فراخوانی روش createCredential() با شیء CredentialManager، کلید بازیابی ایجاد کنید.

// createRestoreRequest contains the details sent by the server 
val response = credentialManager.createCredential(context, createRestoreRequest)

نکات کلیدی درباره کد

  • شیء CreateRestoreCredentialRequest حاوی فیلدهای زیر است:

    • ‫requestJson: گزینه‌های ایجاد اطلاعات کاربری که توسط سرور برنامه در قالب Web Authentication API برای PublicKeyCredentialCreationOptionsJSON ارسال شده است.
    • ‫isCloudBackupEnabled: فیلد Boolean برای تعیین اینکه آیا کلید بازیابی باید در فضای ابری پشتیبان‌گیری شود یا نه. به‌طور پیش‌فرض، این پرچم true است. این فیلد این مقادیر را دارد:

      • ‫true: (توصیه‌شده) این مقدار پشتیبان‌گیری از کلیدهای بازیابی را در فضای ابری فعال می‌کند، به‌شرطی که کاربر «پشتیبان‌گیری Google» و رمزگذاری سرتاسر (مانند قفل صفحه) را فعال کرده باشد.
      • false: این مقدار کلید را به‌صورت محلی و نه در فضای ابری ذخیره می‌کند. اگر کاربر انتخاب کند که از ابر بازیابی کند، کلید در دستگاه جدید دردسترس نیست.

مدیریت پاسخ ایجاد اطلاعات اعتباری

‫Credential Manager API پاسخی از نوع CreateRestoreCredentialResponse برمی‌گرداند. این پاسخ حاوی پاسخ ثبت اعتبارنامه کلید عمومی در قالب JSON است.

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

درطول فرایند ایجاد کلید بازیابی، این استثناها را مدیریت کنید:

  • CreateRestoreCredentialDomException: این استثنا زمانی رخ می‌دهد که requestJson نامعتبر باشد و از قالب WebAuthn برای PublicKeyCredentialCreationOptionsJSON پیروی نکند.
  • E2eeUnavailableException: این استثنا زمانی رخ می‌دهد که isCloudBackupEnabled روی true تنظیم شده باشد، اما دستگاه کاربر پشتیبان‌گیری داده یا رمزگذاری سرتاسر (مثل قفل صفحه) نداشته باشد.
    برای اطمینان از اینکه «بازگرداندن اعتبارنامه‌ها» در همه موارد ایجاد می‌شود، باید E2eeUnavailableException را به‌طور صریح با فراخوانی createCredential با isCloudBackupEnabled تنظیم‌شده روی true مدیریت کنید. اگر E2eeUnavailableException پرتاب شد، آن را بگیرید و createCredential را دوباره با isCloudBackupEnabled تنظیم‌شده روی false فراخوانی کنید.
  • IllegalArgumentException: این استثنا زمانی رخ می‌دهد که createRestoreRequest خالی باشد یا JSON معتبر نباشد، یا اگر user.id معتبری نداشته باشد که با مشخصات WebAuthn مطابقت داشته باشد.

ورود به سیستم با کلید بازیابی

از «بازگرداندن اعتبارنامه‌ها» برای ورود بی‌صدا به سیستم کاربر درطول فرایند راه‌اندازی دستگاه استفاده کنید.

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

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

دریافت کلید بازیابی

برای دریافت کلید بازیابی در دستگاه جدید، روش getCredential() را در شیء CredentialManager فراخوانی کنید.

توصیه می‌شود کلید بازیابی را در هر دو سناریو زیر واکشی کنید:

  • در اولین راه‌اندازی برنامه در دستگاه. بازیابی اطلاعات کاربری در این سناریو مستقل از بازیابی داده‌های برنامه است.
  • اگر پشتیبان‌گیری و بازیابی داده‌های برنامه فعال است، بلافاصله پس‌از بازیابی داده‌های برنامه، کلید بازیابی را دریافت کنید. از BackupAgent برای پیکربندی پشتیبان‌گیری برنامه‌تان استفاده کنید و مطمئن شوید که عملکرد getCredential را در بازخوانی onRestoreFinished تکمیل می‌کنید. از روش onRestore استفاده نکنید، زیرا این روش فقط برای پشتیبان‌گیری‌های کلید-مقدار فراخوانی می‌شود، درحالی‌که onRestoreFinished به‌طور قابل‌اعتمادی برای هر نوع بازیابی پشتیبان فراخوانی می‌شود. این کار از تأخیرهای احتمالی هنگام باز کردن دستگاه جدید برای اولین‌بار توسط کاربران جلوگیری می‌کند و به کاربران اجازه می‌دهد بدون انتظار برای باز کردن برنامه شما، با آن تعامل داشته باشند. برای مثال، این کار به برنامه شما اجازه می‌دهد قبل‌از اینکه کاربر برای اولین‌بار برنامه را در دستگاه جدید باز کند، برای او اعلان ارسال کند، که این امر به‌ویژه برای برنامه‌های پیام‌رسانی یا ارتباطی مرتبط است.

اگر BackupAgent جدیدی ایجاد کنید و قبلاً پشتیبان‌گیری را با allowBackup="true" فعال کرده باشید، مقدار بولی android:fullBackupOnly="true" را در مانیفست برنامه‌تان تنظیم کنید. این کار تضمین می‌کند که رفتار پشتیبان‌گیری و بازیابی برنامه‌تان حفظ شود.

// Fetch the options required to get the restore key
val authenticationJson = fetchAuthenticationJson()

// Create the GetRestoreCredentialRequest object
val options = GetRestoreCredentialOption(authenticationJson)
val getRequest = GetCredentialRequest(listOf(options))

val response = credentialManager.getCredential(context, getRequest)

// Type-check and extract the restore credential
val credential = response.credential as RestoreCredential

میاناهای برنامه‌سازی کاربردی Credential Manager پاسخی از نوع GetCredentialResponse برمی‌گردانند. اعتبارنامه موجود در این پاسخ صراحتاً از نوع RestoreCredential است که کلید عمومی را نگه می‌دارد.

مدیریت پاسخ ورود به سیستم

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

حذف کلید بازیابی

«مدیر اطلاعات کاربری» بدون حالت است و از فعالیت کاربر آگاه نیست، بنابراین کلیدهای بازیابی را پس‌از استفاده به‌طور خودکار حذف نمی‌کند. برای حذف کلید بازیابی، روش clearCredentialState را فراخوانی کنید. برای امنیت، هرگاه کاربر از سیستم خارج شد، کلید را حذف کنید. این کار تضمین می‌کند که دفعه بعد که کاربر برنامه را در همان دستگاه باز می‌کند، کاربر از سیستم خارج شده باشد و از او خواسته شود دوباره به سیستم وارد شود.

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

کلیدهای بازیابی فقط در شرایط زیر برداشته می‌شوند:

  • کنش‌های سطح سیستم: کاربران برنامه را حذف نصب می‌کنند یا داده‌های آن را پاک می‌کنند.
  • فراخوانی‌های سطح برنامه: با فراخوانی clearCredentialState() هنگام رسیدگی به خروج کاربر از سیستم در کد برنامه‌تان، کلید را به‌صورت برنامه‌نویسی‌شده حذف کنید.

وقتی کاربر از سیستم برنامه شما خارج می‌شود، روش clearCredentialState() را در شیء CredentialManager فراخوانی کنید.

// Create a ClearCredentialStateRequest object
val clearRequest = ClearCredentialStateRequest(TYPE_CLEAR_RESTORE_CREDENTIAL)

// When the user logs out, delete the restore key
val response = credentialManager.clearCredentialState(clearRequest)