نسخه 2024 Q4: با نحوه ساده کردن سفرهای احراز هویت با استفاده از Credential Manager API در برنامه Android خود آشنا شوید

1. قبل از شروع

راه حل های احراز هویت سنتی تعدادی از چالش های امنیتی و قابلیت استفاده را ایجاد می کنند.

رمز عبور به طور گسترده استفاده می شود اما ...

  • به راحتی فراموش می شود
  • کاربران برای ایجاد رمزهای عبور قوی نیاز به دانش دارند.
  • فیش کردن، برداشت و پخش مجدد توسط مهاجمان آسان است.

Android روی ایجاد Credential Manager API کار کرده است تا تجربه ورود به سیستم را ساده کند و خطرات امنیتی را با پشتیبانی از کلیدهای عبور ، نسل بعدی استاندارد صنعتی برای احراز هویت بدون رمز عبور، برطرف کند.

Credential Manager پشتیبانی از کلیدهای عبور را گرد هم می آورد و آن را با روش های احراز هویت سنتی مانند گذرواژه ها، ورود به سیستم با Google و غیره ترکیب می کند.

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

در این کد لبه، یاد خواهید گرفت که چگونه با استفاده از کلیدهای عبور و رمز عبور با استفاده از Credential Manager API ثبت نام کنید و از آنها برای اهداف احراز هویت آینده استفاده کنید. 2 جریان وجود دارد که عبارتند از:

  • ثبت نام: با استفاده از کلیدهای عبور و رمز عبور.
  • ورود به سیستم: با استفاده از کلیدهای عبور و رمز عبور ذخیره شده.

پیش نیازها

  • آشنایی اولیه با نحوه اجرای برنامه ها در اندروید استودیو.
  • درک اولیه از جریان احراز هویت در برنامه های اندروید.
  • درک اولیه از کلیدهای عبور .

چیزی که یاد خواهید گرفت

  • نحوه ایجاد رمز عبور
  • نحوه ذخیره رمز عبور در پسورد منیجر
  • نحوه احراز هویت کاربران با رمز عبور یا رمز عبور ذخیره شده

آنچه شما نیاز دارید

یکی از ترکیب دستگاه های زیر:

  • دستگاه اندرویدی که اندروید 9 یا بالاتر (برای کلیدهای عبور) و اندروید 4.4 یا بالاتر (برای احراز هویت رمز عبور از طریق Credential Manager API) را اجرا می‌کند.
  • دستگاه ترجیحا با سنسور بیومتریک.
  • مطمئن شوید که یک بیومتریک (یا قفل صفحه) ثبت کرده اید.
  • نسخه پلاگین Kotlin: 1.8.10

2. راه اندازی شوید

  1. این مخزن را از شعبه credman_codelab در لپ تاپ خود شبیه سازی کنید: https://github.com/android/identity-samples/tree/credman_codelab
git clone -b credman_codelab https://github.com/android/identity-samples.git
  1. به ماژول CredentialManager رفته و پروژه را در اندروید استودیو باز کنید.

بیایید وضعیت اولیه برنامه را ببینیم

برای مشاهده نحوه عملکرد اولیه برنامه، مراحل زیر را دنبال کنید:

  1. برنامه را راه اندازی کنید.
  2. یک صفحه اصلی با دکمه ثبت نام و ورود مشاهده می کنید. این دکمه‌ها هنوز هیچ کاری انجام نمی‌دهند، اما عملکرد آن‌ها را در بخش‌های آینده فعال خواهیم کرد.

7a6fe80f4cf877a8.jpeg

3. امکان ثبت نام با استفاده از کلیدهای عبور را اضافه کنید

هنگام ثبت نام برای یک حساب جدید در یک برنامه Android که از Credential Manager API استفاده می کند، کاربران می توانند یک رمز عبور برای حساب خود ایجاد کنند. این کلید عبور به‌طور ایمن در ارائه‌دهنده اعتبار انتخابی کاربر ذخیره می‌شود و برای ورود به سیستم در آینده استفاده می‌شود، بدون اینکه کاربر هر بار رمز عبور خود را وارد کند.

اکنون، با استفاده از بیومتریک/قفل صفحه، یک رمز عبور ایجاد می‌کنید و اعتبار کاربری را ثبت می‌کنید.

با رمز عبور ثبت نام کنید

کد داخل Credential Manager/app/main/java/SignUpFragment.kt، یک فیلد متنی "نام کاربری" و یک دکمه برای ثبت نام با یک رمز عبور تعریف می کند.

1f4c50daa2551f1.jpeg

چالش و سایر پاسخ‌های json را به یک فراخوانی ()createPasskey ارسال کنید

قبل از ایجاد رمز عبور، باید اطلاعات لازم را از سرور درخواست کنید تا در طول تماس CredentialCredential () به API Credential Manager منتقل شود.

شما در حال حاضر یک پاسخ ساختگی در دارایی های پروژه خود به نام RegFromServer.txt دارید که پارامترهای لازم را در این کد لبه برمی گرداند.

  • در برنامه خود، به SignUpFragment.kt بروید، متد signUpWithPasskeys را پیدا کنید، جایی که منطق ایجاد یک رمز عبور و اجازه ورود کاربر را می نویسید. می توانید روش را در همان کلاس پیدا کنید.
  • بلوک else را با یک نظر برای فراخوانی createPasskey() علامت بزنید و کد زیر را جایگزین کنید:

SignUpFragment.kt

//TODO : Call createPasskey() to signup with passkey

val data = createPasskey()

این روش زمانی فراخوانی می شود که یک نام کاربری معتبر روی صفحه پر کنید.

  • در داخل متد createPasskey() ، باید یک CreatePublicKeyCredentialRequest() با پارامترهای لازم برگردانده شده ایجاد کنید.

SignUpFragment.kt

//TODO create a CreatePublicKeyCredentialRequest() with necessary registration json from server

val request = CreatePublicKeyCredentialRequest(fetchRegistrationJsonFromServer())

متد fetchRegistrationJsonFromServer() یک پاسخ JSON PublicKeyCredentialCreationOptions سرور شبیه‌سازی شده را از دارایی‌ها می‌خواند و JSON ثبت نام را که باید هنگام ایجاد رمز عبور ارسال شود، برمی‌گرداند.

  • متد fetchRegistrationJsonFromServer() را پیدا کنید و TODO را با کد زیر جایگزین کنید تا JSON را برگردانید و همچنین دستور بازگشت رشته خالی را حذف کنید :

SignUpFragment.kt

//TODO fetch registration mock response

val response = requireContext().readFromAsset("RegFromServer")

//Update userId,challenge, name and Display name in the mock
return response.replace("<userId>", getEncodedUserId())
   .replace("<userName>", binding.username.text.toString())
   .replace("<userDisplayName>", binding.username.text.toString())
   .replace("<challenge>", getEncodedChallenge())
  • این JSON ناقص است و دارای 4 فیلد است که باید جایگزین شوند.
  • UserId باید منحصر به فرد باشد تا کاربر بتواند چندین کلید عبور ایجاد کند (در صورت نیاز). مقدار userId ایجاد شده را جایگزین <userId> کنید.
  • <challenge> همچنین باید منحصر به فرد باشد، بنابراین شما یک چالش منحصر به فرد تصادفی ایجاد خواهید کرد. روش از قبل در کد شما موجود است.

یک پاسخ PublicKeyCredentialCreationOptions سرور واقعی ممکن است گزینه های بیشتری را برگرداند. نمونه ای از برخی از این فیلدها در زیر آورده شده است:

{
  "challenge": String,
  "rp": {
    "name": String,
    "id": String
  },
  "user": {
    "id": String,
    "name": String,
    "displayName": String
  },
  "pubKeyCredParams": [
    {
      "type": "public-key",
      "alg": -7
    },
    {
      "type": "public-key",
      "alg": -257
    }
  ],
  "timeout": 1800000,
  "attestation": "none",
  "excludeCredentials": [],
  "authenticatorSelection": {
    "authenticatorAttachment": "platform",
    "requireResidentKey": true,
    "residentKey": "required",
    "userVerification": "required"
  }
}

جدول زیر برخی از پارامترهای مهم در یک شی PublicKeyCredentialCreationOptions را توضیح می دهد:

پارامترها

توضیحات

challenge

یک رشته تصادفی تولید شده توسط سرور که حاوی آنتروپی کافی برای حدس زدن آن است. باید حداقل 16 بایت باشد. این مورد ضروری است اما در هنگام ثبت نام استفاده نمی شود مگر اینکه گواهینامه انجام شود.

user.id

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

user.name

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

user.displayName

این فیلد یک نام اختیاری و کاربرپسندتر برای حساب است.

rp.id

نهاد متکی با جزئیات درخواست شما مطابقت دارد. دارای ویژگی های زیر است:

  • name (الزامی): نام برنامه شما
  • ID (اختیاری): مربوط به دامنه یا زیر دامنه است. در صورت عدم وجود، از دامنه فعلی استفاده می شود.
  • icon (اختیاری).

pubKeyCredParams

فهرست الگوریتم های مجاز و انواع کلید. این لیست باید حداقل دارای یک عنصر باشد.

excludeCredentials

کاربری که سعی در ثبت یک دستگاه دارد ممکن است دستگاه های دیگری را ثبت کرده باشد. برای محدود کردن ایجاد چندین اعتبار برای یک حساب کاربری در یک احراز هویت، می‌توانید این دستگاه‌ها را نادیده بگیرید. عضو transports ، در صورت ارائه، باید حاوی نتیجه فراخوانی getTransports() در هنگام ثبت هر اعتبار باشد.

authenticatorSelection.authenticatorAttachment

نشان می دهد که آیا دستگاه باید روی پلت فرم وصل شود یا خیر یا نیازی به این کار وجود ندارد. این مقدار را روی platform قرار دهید. این نشان می دهد که شما یک احراز هویت می خواهید که در دستگاه پلت فرم تعبیه شده باشد، و از کاربر خواسته نمی شود که مثلاً یک کلید امنیتی USB را وارد کند.

residentKey

مقدار required برای ایجاد یک رمز عبور را نشان می دهد.

اعتبارنامه ایجاد کنید

  1. هنگامی که یک CreatePublicKeyCredentialRequest() ایجاد کردید، باید تماس createCredential() با درخواست ایجاد شده فراخوانی کنید.

SignUpFragment.kt

//TODO call createCredential() with createPublicKeyCredentialRequest

try {
   response = credentialManager.createCredential(
       requireActivity(),
       request
   ) as CreatePublicKeyCredentialResponse
} catch (e: CreateCredentialException) {
   configureProgress(View.INVISIBLE)
   handlePasskeyFailure(e)
}
  • شما اطلاعات مورد نیاز را به createCredential() منتقل می کنید.
  • پس از موفقیت آمیز بودن درخواست، صفحه پایینی را روی صفحه نمایش خود خواهید دید که از شما می خواهد یک کلید عبور ایجاد کنید.
  • اکنون کاربران می توانند هویت خود را از طریق بیومتریک یا قفل صفحه و غیره تأیید کنند.
  • شما نمایان بودن نماهای رندر شده را کنترل می‌کنید و در صورت عدم موفقیت یا ناموفق بودن درخواست به دلایلی، استثنائات را مدیریت می‌کنید. در اینجا پیام های خطا ثبت شده و در برنامه در یک گفتگوی خطا نشان داده می شوند. شما می توانید گزارش های کامل خطا را از طریق Android Studio یا دستور adb debug بررسی کنید.

1ea8ace66135de1e.png

  1. در نهایت باید مراحل ثبت نام را تکمیل کنید. این برنامه یک اعتبار کلید عمومی را به سرور ارسال می کند که آن را برای کاربر فعلی ثبت می کند.

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

در داخل متد signUpWithPasskeys() ، نظر مربوطه را پیدا کنید و کد زیر را جایگزین کنید:

SignUpFragment.kt

//TODO : complete the registration process after sending public key credential to your server and let the user in

data?.let {
   registerResponse()
   DataProvider.setSignedInThroughPasskeys(true)
   listener.showHome()
}
  • registerResponse() true را برمی گرداند که نشان می دهد سرور ساختگی کلید عمومی را برای استفاده در آینده ذخیره کرده است.
  • پرچم setSignedInThroughPasskeys را روی true تنظیم کنید.
  • پس از ورود به سیستم، کاربر خود را به صفحه اصلی هدایت می کنید.

یک PublicKeyCredential واقعی ممکن است حاوی فیلدهای بیشتری باشد. نمونه ای از این فیلدها در زیر نشان داده شده است:

{
  "id": String,
  "rawId": String,
  "type": "public-key",
  "response": {
    "clientDataJSON": String,
    "attestationObject": String,
  }
}

جدول زیر برخی از پارامترهای مهم در یک شی PublicKeyCredential را توضیح می دهد:

پارامترها

توضیحات

id

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

rawId

یک نسخه شی ArrayBuffer شناسه اعتبار.

response.clientDataJSON

یک شی ArrayBuffer داده های مشتری را رمزگذاری می کند.

response.attestationObject

یک شیء تصدیق رمزگذاری شده ArrayBuffer . حاوی اطلاعات مهمی مانند شناسه RP، پرچم‌ها و کلید عمومی است.

برنامه را اجرا کنید و می توانید روی دکمه Sign up with passkeys کلیک کنید و یک رمز عبور ایجاد کنید.

4. رمز عبور را در Credential Provider ذخیره کنید

در این برنامه، در داخل صفحه ثبت نام خود، از قبل یک ثبت نام با نام کاربری و رمز عبور دارید که برای اهداف نمایشی پیاده سازی شده است.

برای ذخیره اعتبار رمز عبور کاربر با ارائه دهنده رمز عبور خود، یک CreatePasswordRequest برای عبور به createCredential() برای ذخیره رمز عبور پیاده سازی می کنید.

  • متد signUpWithPassword() را پیدا کنید، TODO را با یک فراخوانی createPassword جایگزین کنید:

SignUpFragment.kt

//TODO : Save the user credential password with their password provider

createPassword()
  • در داخل متد createPassword() ، باید درخواست رمز عبور را مانند این ایجاد کنید، TODO را با کد زیر جایگزین کنید:

SignUpFragment.kt

//TODO : CreatePasswordRequest with entered username and password

val request = CreatePasswordRequest(
   binding.username.text.toString(),
   binding.password.text.toString()
)
  • در مرحله بعد، در داخل متد createPassword() ، یک اعتبار با درخواست ایجاد رمز عبور ایجاد کنید و اعتبار رمز عبور کاربر را با ارائه دهنده رمز عبور ذخیره کنید. TODO را با کد زیر جایگزین کنید:

SignUpFragment.kt

//TODO : Create credential with created password request


try {
   credentialManager.createCredential(requireActivity(), request) as CreatePasswordResponse
} catch (e: Exception) {
   Log.e("Auth", " Exception Message : " + e.message)
}
  • اکنون اعتبار رمز عبور را با موفقیت در ارائه‌دهنده رمز عبور کاربر ذخیره کرده‌اید تا با یک گذرواژه احراز هویت را تنها با یک ضربه بزنید.

5. قابلیت احراز هویت با رمز عبور یا رمز عبور را اضافه کنید

اکنون آماده هستید که از آن به عنوان راهی برای احراز هویت به برنامه خود استفاده کنید.

76e81460b26f9798.png

چالش و گزینه های دیگر را برای عبور به فراخوانی getPasskey() دریافت کنید

قبل از اینکه از کاربر بخواهید احراز هویت کند، باید پارامترهایی را برای ارسال در WebAuthn JSON از سرور درخواست کنید، از جمله یک چالش.

شما قبلاً یک پاسخ ساختگی در دارایی های خود دارید ( AuthFromServer.txt ) که چنین پارامترهایی را در این کد لبه برمی گرداند.

  • در برنامه خود، به SignInFragment.kt بروید، روش signInWithSavedCredentials را پیدا کنید که در آن منطق احراز هویت از طریق رمز عبور ذخیره شده یا رمز عبور را می نویسید و به کاربر اجازه می دهید وارد شود:
  • بلوک else را با یک نظر برای فراخوانی createPasskey() بررسی کنید و کد زیر را جایگزین کنید:

SignInFragment.kt

//TODO : Call getSavedCredentials() method to signin using passkey/password

val data = getSavedCredentials()
  • در داخل متد ()getSavedCredentials، باید یک GetPublicKeyCredentialOption() با پارامترهای لازم برای دریافت اعتبار از ارائه دهنده اعتبار خود ایجاد کنید.

SigninFragment.kt

//TODO create a GetPublicKeyCredentialOption() with necessary registration json from server

val getPublicKeyCredentialOption =
   GetPublicKeyCredentialOption(fetchAuthJsonFromServer(), null)

متد fetchAuthJsonFromServer() پاسخ JSON احراز هویت را از دارایی ها می خواند و احراز هویت JSON را برای بازیابی همه کلیدهای عبور مرتبط با این حساب کاربری بازمی گرداند.

دومین پارامتر GetPublicKeyCredentialOption() clientDataHash است - یک هش که برای تأیید هویت طرف متکی استفاده می شود. این را فقط در صورتی تنظیم کنید که GetCredentialRequest.origin را تنظیم کرده باشید. برای برنامه نمونه، این روی null تنظیم شده است.

  • متد fetchAuthJsonFromServer() را پیدا کنید و TODO را با کد زیر جایگزین کنید تا json را برگردانید و همچنین دستور بازگشت رشته خالی را حذف کنید :

SignInFragment.kt

//TODO fetch authentication mock json

return requireContext().readFromAsset("AuthFromServer")

توجه: سرور این کد لبه برای برگرداندن JSON طراحی شده است که تا حد امکان شبیه فرهنگ لغت PublicKeyCredentialRequestOptions است که به فراخوانی getCredential() API ارسال می شود. قطعه کد زیر شامل چند گزینه نمونه است که می توانید در یک پاسخ واقعی دریافت کنید:

{
  "challenge": String,
  "rpId": String,
  "userVerification": "",
  "timeout": 1800000
}

جدول زیر برخی از پارامترهای مهم در یک شی PublicKeyCredentialRequestOptions را توضیح می دهد:

پارامترها

توضیحات

challenge

یک چالش ایجاد شده توسط سرور در یک شی ArrayBuffer . این برای جلوگیری از حملات تکراری لازم است. هرگز یک چالش را در یک پاسخ دو بار قبول نکنید. آن را یک توکن CSRF در نظر بگیرید.

rpId

شناسه RP یک دامنه است. یک وب سایت می تواند دامنه یا پسوند قابل ثبت خود را مشخص کند. این مقدار باید با پارامتر rp.id مورد استفاده در هنگام ایجاد رمز عبور مطابقت داشته باشد.

  • در مرحله بعد باید یک شی PasswordOption() ایجاد کنید تا تمام رمزهای عبور ذخیره شده در ارائه دهنده رمز عبور خود را از طریق Credential Manager API برای این حساب کاربری بازیابی کنید. در داخل متد getSavedCredentials() ، TODO را پیدا کرده و با عبارت زیر جایگزین کنید:

SigninFragment.kt

//TODO create a PasswordOption to retrieve all the associated user's password

val getPasswordOption = GetPasswordOption()

مدارک دریافت کنید

  • در مرحله بعد باید درخواست getCredential() را با تمام گزینه های بالا فراخوانی کنید تا اعتبارنامه های مرتبط را بازیابی کنید:

SignInFragment.kt

//TODO call getCredential() with required credential options

val result = try {
   credentialManager.getCredential(
       requireActivity(),
       GetCredentialRequest(
           listOf(
               getPublicKeyCredentialOption,
               getPasswordOption
           )
     )
   )
} catch (e: Exception) {
   configureViews(View.INVISIBLE, true)
   Log.e("Auth", "getCredential failed with exception: " + e.message.toString())
   activity?.showErrorAlert(
       "An error occurred while authenticating through saved credentials. Check logs for additional details"
   )
   return null
}

if (result.credential is PublicKeyCredential) {
   val cred = result.credential as PublicKeyCredential
   DataProvider.setSignedInThroughPasskeys(true)
   return "Passkey: ${cred.authenticationResponseJson}"
}
if (result.credential is PasswordCredential) {
   val cred = result.credential as PasswordCredential
   DataProvider.setSignedInThroughPasskeys(false)
   return "Got Password - User:${cred.id} Password: ${cred.password}"
}
if (result.credential is CustomCredential) {
   //If you are also using any external sign-in libraries, parse them here with the utility functions provided.
}

  • شما اطلاعات مورد نیاز را به getCredential() می دهید. این فهرستی از گزینه‌های اعتبار و یک زمینه فعالیت را برای نمایش گزینه‌های صفحه پایین در آن زمینه می‌گیرد.
  • پس از موفقیت آمیز بودن درخواست، صفحه پایینی را در صفحه نمایش خود مشاهده خواهید کرد که تمام اعتبارنامه های ایجاد شده برای حساب مرتبط را فهرست می کند.
  • اکنون کاربران می توانند هویت خود را از طریق بیومتریک یا قفل صفحه و غیره تأیید کنند تا اعتبار انتخاب شده را تأیید کنند.
  • اگر اعتبار انتخاب شده یک PublicKeyCredential است، پرچم setSignedInThroughPasskeys را true تنظیم کنید. در غیر این صورت آن را روی false قرار دهید.

قطعه کد زیر شامل یک نمونه شی PublicKeyCredential است:

{
  "id": String
  "rawId": String
  "type": "public-key",
  "response": {
    "clientDataJSON": String
    "authenticatorData": String
    "signature": String
    "userHandle": String
  }
}

جدول زیر جامع نیست، اما شامل پارامترهای مهم در شی PublicKeyCredential است:

پارامترها

توضیحات

id

شناسه رمزگذاری شده Base64URL اعتبار کلید عبور تأیید شده.

rawId

یک نسخه شی ArrayBuffer شناسه اعتبار.

response.clientDataJSON

یک شی ArrayBuffer از داده های مشتری. این فیلد حاوی اطلاعاتی مانند چالش و مبدا است که سرور RP باید تأیید کند.

response.authenticatorData

یک شی ArrayBuffer از داده های احراز هویت. این فیلد حاوی اطلاعاتی مانند RP ID است.

response.signature

یک شی ArrayBuffer از امضا. این مقدار هسته اعتبارنامه است و باید در سرور تأیید شود.

response.userHandle

یک شی ArrayBuffer که شامل شناسه کاربری تنظیم شده در زمان ایجاد است. اگر سرور باید مقادیر شناسه ای را که استفاده می کند انتخاب کند، یا اگر backend بخواهد از ایجاد نمایه در شناسه های اعتبارنامه جلوگیری کند، می توان از این مقدار به جای شناسه اعتبار استفاده کرد.

  • در نهایت، باید فرآیند احراز هویت را تکمیل کنید. به طور معمول، پس از اینکه کاربر احراز هویت رمز عبور را کامل کرد، برنامه یک اعتبار کلید عمومی حاوی یک ادعای احراز هویت را به سرور ارسال می کند که این ادعا را تأیید می کند و کاربر را تأیید می کند.

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

در متد signInWithSavedCredentials() ، نظر مربوطه را پیدا کنید و کد زیر را جایگزین کنید:

SignInFragment.kt

//TODO : complete the authentication process after validating the public key credential to your server and let the user in.

data?.let {
   sendSignInResponseToServer()
   listener.showHome()
}
  • sendSigninResponseToServer() درست را نشان می دهد که نشان می دهد سرور (ساختار) کلید عمومی را برای استفاده در آینده تایید کرده است.
  • پس از ورود به سیستم، کاربر خود را به صفحه اصلی هدایت می کنید.

برنامه را اجرا کنید و برای ورود به سیستم > با کلیدهای عبور/گذرواژه ذخیره شده وارد شوید و سعی کنید با استفاده از اطلاعات کاربری ذخیره شده وارد شوید.

آن را امتحان کنید

ایجاد کلیدهای عبور، ذخیره گذرواژه در Credential Manager، و احراز هویت از طریق کلیدهای عبور یا رمز عبور ذخیره شده را با استفاده از Credential Manager API در برنامه Android خود اجرا کردید.

6. تبریک می گویم!

شما این کد لبه را تمام کردید! اگر می خواهید راه حل نهایی را بررسی کنید، که در https://github.com/android/identity-samples/tree/main/CredentialManager موجود است

اگر سؤالی دارید، از آنها در StackOverflow با یک برچسب passkey بپرسید.

بیشتر بدانید