ลงชื่อเข้าใช้ผู้ใช้ด้วยตัวจัดการข้อมูลเข้าสู่ระบบ

Credential Manager เป็น Jetpack API ที่รองรับวิธีการลงชื่อเข้าใช้หลายวิธี เช่น ชื่อผู้ใช้และรหัสผ่าน พาสคีย์ และโซลูชันการลงชื่อเข้าใช้แบบรวมศูนย์ (เช่น การลงชื่อเข้าใช้ด้วย Google) ใน API เดียว จึงช่วยลดความซับซ้อนของการผสานรวมสำหรับ นักพัฒนาแอป

นอกจากนี้ Credential Manager ยังรวบรวมอินเทอร์เฟซการลงชื่อเข้าใช้ในวิธีการตรวจสอบสิทธิ์ต่างๆ เข้าด้วยกัน เพื่อให้การลงชื่อเข้าใช้แอปชัดเจนและง่ายขึ้น ไม่ว่าผู้ใช้จะเลือกวิธีการใดก็ตาม

หน้านี้อธิบายแนวคิดของพาสคีย์และขั้นตอนในการใช้การรองรับฝั่งไคลเอ็นต์สำหรับโซลูชันการตรวจสอบสิทธิ์ ซึ่งรวมถึงพาสคีย์ โดยใช้ Credential Manager API นอกจากนี้ เรายังมีหน้าคำถามที่พบบ่อยแยกต่างหากซึ่งมีคำตอบสำหรับคำถามที่เฉพาะเจาะจงและมีรายละเอียดมากขึ้น

เกี่ยวกับพาสคีย์

พาสคีย์เป็นตัวแทนที่ปลอดภัยกว่าและใช้งานง่ายกว่าเมื่อเทียบกับรหัสผ่าน พาสคีย์ช่วยให้ผู้ใช้ลงชื่อเข้าใช้แอปและเว็บไซต์ได้โดยใช้เซ็นเซอร์ข้อมูลไบโอเมตริก (เช่น ลายนิ้วมือหรือการจดจำใบหน้า), PIN หรือรูปแบบ ซึ่งจะมอบประสบการณ์การลงชื่อเข้าใช้ที่ราบรื่น ให้แก่ผู้ใช้โดยไม่ต้องจดจำชื่อผู้ใช้หรือ รหัสผ่าน

พาสคีย์ใช้ WebAuthn (การตรวจสอบสิทธิ์ผ่านเว็บ) ซึ่งเป็นมาตรฐานที่พัฒนาขึ้นร่วมกันโดย FIDO Alliance และ World Wide Web Consortium (W3C) WebAuthn ใช้ วิทยาการเข้ารหัสคีย์สาธารณะเพื่อตรวจสอบสิทธิ์ผู้ใช้ เว็บไซต์หรือแอปที่ผู้ใช้ลงชื่อเข้าใช้จะดูและจัดเก็บคีย์สาธารณะได้ แต่จะดูคีย์ส่วนตัวไม่ได้ ระบบจะเก็บคีย์ส่วนตัวไว้เป็นความลับและปลอดภัย และเนื่องจากคีย์มีความเฉพาะตัวและ เชื่อมโยงกับเว็บไซต์หรือแอป พาสคีย์จึงป้องกันฟิชชิงได้ ซึ่งช่วยเพิ่มความปลอดภัยยิ่งขึ้น

เครื่องมือจัดการข้อมูลเข้าสู่ระบบช่วยให้ผู้ใช้สร้างพาสคีย์และจัดเก็บไว้ในเครื่องมือจัดการรหัสผ่านบน Google ได้

อ่านการตรวจสอบสิทธิ์ผู้ใช้ด้วยพาสคีย์เพื่อดูคำแนะนำเกี่ยวกับวิธีใช้ ขั้นตอนการตรวจสอบสิทธิ์ด้วยพาสคีย์ที่ราบรื่นกับเครื่องมือจัดการข้อมูลเข้าสู่ระบบ

สิ่งที่ต้องมีก่อน

หากต้องการใช้เครื่องมือจัดการข้อมูลเข้าสู่ระบบ ให้ทำตามขั้นตอนในส่วนนี้

ใช้แพลตฟอร์มเวอร์ชันล่าสุด

เครื่องมือจัดการข้อมูลเข้าสู่ระบบรองรับ Android 4.4 (API ระดับ 19) ขึ้นไป

เพิ่มการอ้างอิงไปยังแอป

เพิ่มการขึ้นต่อกันต่อไปนี้ลงในสคริปต์บิลด์ของโมดูลแอป

implementation(libs.androidx.credentials)  // optional - needed for credentials support from play services, for devices running // Android 13 and below. implementation(libs.androidx.credentials.play.services.auth) 

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีลดขนาด ทำให้สับสน และเพิ่มประสิทธิภาพแอป

เพิ่มการรองรับลิงก์เนื้อหาดิจิทัล

หากต้องการเปิดใช้การรองรับพาสคีย์สำหรับแอป Android ให้เชื่อมโยงแอปกับ เว็บไซต์ที่แอปเป็นเจ้าของ คุณประกาศการเชื่อมโยงนี้ได้โดยทำตาม ขั้นตอนต่อไปนี้

  1. สร้างไฟล์ JSON ของลิงก์เนื้อหาดิจิทัล (Digital Asset Links) ตัวอย่างเช่น หากต้องการประกาศว่าเว็บไซต์ https://signin.example.com และแอป Android ที่มีชื่อแพ็กเกจ com.example สามารถแชร์ข้อมูลเข้าสู่ระบบได้ ให้สร้างไฟล์ชื่อ assetlinks.json ที่มีเนื้อหาต่อไปนี้

    [   {     "relation" : [       "delegate_permission/common.handle_all_urls",       "delegate_permission/common.get_login_creds"     ],     "target" : {       "namespace" : "android_app",       "package_name" : "com.example.android",       "sha256_cert_fingerprints" : [         SHA_HEX_VALUE       ]     }   } ] 

    ฟิลด์ relation คืออาร์เรย์ของสตริงอย่างน้อย 1 รายการที่อธิบายความสัมพันธ์ที่ประกาศ หากต้องการประกาศว่าแอปและเว็บไซต์แชร์ข้อมูลเข้าสู่ระบบ ให้ระบุความสัมพันธ์เป็น delegate_permission/handle_all_urls และ delegate_permission/common.get_login_creds

    ฟิลด์ target คือออบเจ็กต์ที่ระบุเนื้อหาที่การประกาศ มีผล ฟิลด์ต่อไปนี้จะระบุเว็บไซต์

    namespace web
    site

    URL ของเว็บไซต์ในรูปแบบ https://domain[:optional_port] เช่น https://www.example.com

    domain ต้องมีคุณสมบัติครบถ้วน และ optional_port ต้องละเว้นเมื่อใช้พอร์ต 443 สำหรับ HTTPS

    site เป้าหมายต้องเป็นโดเมนรูทเท่านั้น คุณจะ จำกัดการเชื่อมโยงแอปกับไดเรกทอรีย่อยที่เฉพาะเจาะจงไม่ได้ อย่าใส่เส้นทางใน URL เช่น เครื่องหมายทับต่อท้าย

    ระบบจะไม่พิจารณาว่าโดเมนย่อยตรงกัน กล่าวคือ หากคุณระบุ domain เป็น www.example.com โดเมน www.counter.example.com จะไม่เชื่อมโยงกับแอปของคุณ

    ฟิลด์ต่อไปนี้ระบุแอป Android

    namespace android_app
    package_name ชื่อแพ็กเกจที่ประกาศไว้ในไฟล์ Manifest ของแอป เช่น com.example.android
    sha256_cert_fingerprints ลายนิ้วมือ SHA256 ของ ใบรับรองการลงนามของแอป
  2. โฮสต์ไฟล์ JSON ของลิงก์เนื้อหาดิจิทัลในตำแหน่งต่อไปนี้ในโดเมนการลงชื่อเข้าใช้

    https://domain[:optional_port]/.well-known/assetlinks.json 

    เช่น หากโดเมนการลงชื่อเข้าใช้คือ signin.example.com ให้โฮสต์ไฟล์ JSON ที่ https://signin.example.com/.well-known/assetlinks.json

    ประเภท MIME สำหรับไฟล์ลิงก์เนื้อหาดิจิทัลต้องเป็น JSON ตรวจสอบว่าเซิร์ฟเวอร์ส่งส่วนหัว Content-Type: application/json ในการตอบกลับ

  3. ตรวจสอบว่าโฮสต์อนุญาตให้ Google ดึงไฟล์ลิงก์เนื้อหาดิจิทัล หากคุณมีไฟล์ robots.txt ไฟล์ดังกล่าวต้องอนุญาตให้ตัวแทน Googlebot ดึงข้อมูล /.well-known/assetlinks.json ได้ เว็บไซต์ส่วนใหญ่สามารถอนุญาตให้เอเจนต์อัตโนมัติ ดึงข้อมูลไฟล์ในเส้นทาง /.well-known/ เพื่อให้บริการอื่นๆ เข้าถึงข้อมูลเมตาในไฟล์เหล่านั้นได้

    User-agent: * Allow: /.well-known/ 
  4. เพิ่มบรรทัดต่อไปนี้ลงในไฟล์ Manifest ในส่วน <application>

    <meta-data android:name="asset_statements" android:resource="@string/asset_statements" /> 
  5. หากคุณใช้การลงชื่อเข้าใช้ด้วยรหัสผ่านผ่านเครื่องมือจัดการข้อมูลเข้าสู่ระบบ ให้ทำตาม ขั้นตอนนี้เพื่อกำหนดค่าการลิงก์ชิ้นงานดิจิทัลในไฟล์ Manifest ขั้นตอนนี้ไม่จำเป็นหากคุณใช้เฉพาะพาสคีย์

    ประกาศการเชื่อมโยงในแอป Android โดยเพิ่มออบเจ็กต์ที่ระบุ assetlinks.json ไฟล์ที่จะโหลด คุณต้องกำหนดเครื่องหมายอัญประกาศเดี่ยวและ เครื่องหมายคำพูดที่ใช้ในสตริงเป็นอักขระหลีก เช่น

    <string name="asset_statements" translatable="false"> [{   \"include\": \"https://signin.example.com/.well-known/assetlinks.json\" }] </string> 
    > GET /.well-known/assetlinks.json HTTP/1.1 > User-Agent: curl/7.35.0 > Host: signin.example.com  < HTTP/1.1 200 OK < Content-Type: application/json 

กำหนดค่าเครื่องมือจัดการข้อมูลเข้าสู่ระบบ

หากต้องการกําหนดค่าและเริ่มต้นออบเจ็กต์ CredentialManager ให้เพิ่มตรรกะที่คล้ายกับ รายการต่อไปนี้

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

ระบุช่องข้อมูลเข้าสู่ระบบ

ใน Android 14 ขึ้นไป คุณสามารถใช้แอตทริบิวต์ isCredential เพื่อระบุช่องข้อมูลเข้าสู่ระบบ เช่น ช่องชื่อผู้ใช้หรือรหัสผ่าน แอตทริบิวต์นี้ ระบุว่ามุมมองนี้เป็นช่องข้อมูลเข้าสู่ระบบที่ตั้งใจให้ทำงานร่วมกับ เครื่องมือจัดการข้อมูลเข้าสู่ระบบและผู้ให้บริการข้อมูลเข้าสู่ระบบบุคคลที่สาม ขณะเดียวกันก็ช่วยให้บริการป้อนข้อความอัตโนมัติ ให้คำแนะนำการป้อนข้อความอัตโนมัติได้ดียิ่งขึ้น เมื่อแอปใช้ Credential Manager API ระบบจะแสดงชีตด้านล่างของ Credential Manager พร้อมข้อมูลเข้าสู่ระบบที่ใช้ได้ และไม่จำเป็นต้องแสดงกล่องโต้ตอบการกรอกของกรอกอัตโนมัติสำหรับ ชื่อผู้ใช้หรือรหัสผ่านอีก ในทํานองเดียวกัน คุณไม่จําเป็นต้องแสดงกล่องโต้ตอบบันทึกของกรอกข้อมูลอัตโนมัติสําหรับรหัสผ่าน เนื่องจากแอปจะขอ API ของเครื่องมือจัดการข้อมูลเข้าสู่ระบบเพื่อบันทึกข้อมูลเข้าสู่ระบบ

หากต้องการใช้แอตทริบิวต์ isCredential ให้เพิ่มแอตทริบิวต์นี้ลงในข้อมูลพร็อพเพอร์ตี้ที่เกี่ยวข้อง ดังนี้

<TextView     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:isCredential="true" /> 

ลงชื่อเข้าใช้ผู้ใช้

หากต้องการดึงตัวเลือกพาสคีย์และรหัสผ่านทั้งหมดที่เชื่อมโยงกับบัญชีของผู้ใช้ ให้ทำตามขั้นตอนต่อไปนี้

  1. เริ่มต้นตัวเลือกการตรวจสอบสิทธิ์ด้วยรหัสผ่านและพาสคีย์โดยทำดังนี้

    // Retrieves the user's saved password for your app from their // password provider. val getPasswordOption = GetPasswordOption()  // Get passkey from the user's public key credential provider. val getPublicKeyCredentialOption = GetPublicKeyCredentialOption(     requestJson = requestJson )       
  2. ใช้ตัวเลือกที่ดึงมาจากขั้นตอนก่อนหน้าเพื่อสร้าง คำขอลงชื่อเข้าใช้

    val credentialRequest = GetCredentialRequest(     listOf(getPasswordOption, getPublicKeyCredentialOption), )       
  3. เปิดขั้นตอนการลงชื่อเข้าใช้

    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")         }     } }     

ตัวอย่างต่อไปนี้แสดงวิธีจัดรูปแบบคำขอ JSON เมื่อคุณได้รับพาสคีย์

{   "challenge": "T1xCsnxM2DNL2KdK5CLa6fMhD7OBqho6syzInk_n-Uo",   "allowCredentials": [],   "timeout": 1800000,   "userVerification": "required",   "rpId": "https://passkeys-codelab.glitch.me/" } 

ตัวอย่างต่อไปนี้แสดงลักษณะของการตอบกลับ JSON หลังจากที่คุณได้รับข้อมูลเข้าสู่ระบบคีย์สาธารณะ

{   "id": "KEDetxZcUfinhVi6Za5nZQ",   "type": "public-key",   "rawId": "KEDetxZcUfinhVi6Za5nZQ",   "response": {     "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiVDF4Q3NueE0yRE5MMktkSzVDTGE2Zk1oRDdPQnFobzZzeXpJbmtfbi1VbyIsIm9yaWdpbiI6ImFuZHJvaWQ6YXBrLWtleS1oYXNoOk1MTHpEdll4UTRFS1R3QzZVNlpWVnJGUXRIOEdjVi0xZDQ0NEZLOUh2YUkiLCJhbmRyb2lkUGFja2FnZU5hbWUiOiJjb20uZ29vZ2xlLmNyZWRlbnRpYWxtYW5hZ2VyLnNhbXBsZSJ9",     "authenticatorData": "j5r_fLFhV-qdmGEwiukwD5E_5ama9g0hzXgN8thcFGQdAAAAAA",     "signature": "MEUCIQCO1Cm4SA2xiG5FdKDHCJorueiS04wCsqHhiRDbbgITYAIgMKMFirgC2SSFmxrh7z9PzUqr0bK1HZ6Zn8vZVhETnyQ",     "userHandle": "2HzoHm_hY0CjuEESY9tY6-3SdjmNHOoNqaPDcZGzsr0"   } } 

จัดการข้อยกเว้นเมื่อไม่มีข้อมูลเข้าสู่ระบบ

ในบางกรณี ผู้ใช้อาจไม่มีข้อมูลเข้าสู่ระบบ หรือผู้ใช้อาจ ไม่ให้ความยินยอมในการใช้ข้อมูลเข้าสู่ระบบที่มี หากเรียกใช้ getCredential() และไม่พบข้อมูลเข้าสู่ระบบ ระบบจะแสดงผล NoCredentialException หากเกิดกรณีนี้ขึ้น โค้ดควรจัดการNoCredentialException อินสแตนซ์

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

ใน Android 14 ขึ้นไป คุณสามารถลดเวลาในการตอบสนองเมื่อแสดงตัวเลือกบัญชี ได้โดยใช้วิธี prepareGetCredential() ก่อนเรียกใช้ getCredential()

coroutineScope {     val response = credentialManager.prepareGetCredential(         GetCredentialRequest(             listOf(                 getPublicKeyCredentialOption,                 getPasswordOption             )         )     ) } 

เมธอด prepareGetCredential() ไม่เรียกใช้องค์ประกอบ UI โดยจะช่วยคุณเตรียมงานเพื่อให้คุณเปิดตัวการดำเนินการที่เหลือในการรับข้อมูลเข้าสู่ระบบ (ซึ่งเกี่ยวข้องกับ UI) ผ่าน getCredential() API ได้ในภายหลัง

ระบบจะแสดงผลข้อมูลที่แคชไว้ในออบเจ็กต์ PrepareGetCredentialResponse หากมีข้อมูลเข้าสู่ระบบอยู่แล้ว ระบบจะแคชผลลัพธ์และคุณจะเปิดใช้ getCredential() API ที่เหลือในภายหลังเพื่อแสดงตัวเลือกบัญชีพร้อมข้อมูลที่แคชไว้ได้

ขั้นตอนการลงทะเบียน

คุณสามารถลงทะเบียนผู้ใช้เพื่อตรวจสอบสิทธิ์โดยใช้พาสคีย์หรือรหัสผ่าน

สร้างพาสคีย์

หากต้องการให้ผู้ใช้เลือกที่จะลงทะเบียนพาสคีย์และใช้เพื่อตรวจสอบสิทธิ์อีกครั้ง ให้ลงทะเบียนข้อมูลเข้าสู่ระบบของผู้ใช้โดยใช้ออบเจ็กต์ CreatePublicKeyCredentialRequest

suspend fun createPasskey(requestJson: String, preferImmediatelyAvailableCredentials: Boolean) {     val createPublicKeyCredentialRequest = CreatePublicKeyCredentialRequest(         // Contains the request in JSON format. Uses the standard WebAuthn         // web JSON spec.         requestJson = requestJson,         // Defines whether you prefer to use only immediately available         // credentials, not hybrid credentials, to fulfill this request.         // This value is false by default.         preferImmediatelyAvailableCredentials = preferImmediatelyAvailableCredentials,     )      // Execute CreateCredentialRequest asynchronously to register credentials     // for a user account. Handle success and failure cases with the result and     // exceptions, respectively.     coroutineScope {         try {             val result = credentialManager.createCredential(                 // Use an activity-based context to avoid undefined system                 // UI launching behavior                 context = activityContext,                 request = createPublicKeyCredentialRequest,             )             //  Handle passkey creation result         } catch (e: CreateCredentialException) {             handleFailure(e)         }     } } 
fun handleFailure(e: CreateCredentialException) {     when (e) {         is CreatePublicKeyCredentialDomException -> {             // Handle the passkey DOM errors thrown according to the             // WebAuthn spec.         }         is CreateCredentialCancellationException -> {             // The user intentionally canceled the operation and chose not             // to register the credential.         }         is CreateCredentialInterruptedException -> {             // Retry-able error. Consider retrying the call.         }         is CreateCredentialProviderConfigurationException -> {             // Your app is missing the provider configuration dependency.             // Most likely, you're missing the             // "credentials-play-services-auth" module.         }         is CreateCredentialCustomException -> {             // You have encountered an error from a 3rd-party SDK. If you             // make the API call with a request object that's a subclass of             // CreateCustomCredentialRequest using a 3rd-party SDK, then you             // should check for any custom exception type constants within             // that SDK to match with e.type. Otherwise, drop or log the             // exception.         }         else -> Log.w(TAG, "Unexpected exception type ${e::class.java.name}")     } } 

จัดรูปแบบคำขอ JSON

หลังจากสร้างพาสคีย์แล้ว คุณต้องเชื่อมโยงพาสคีย์กับบัญชีของผู้ใช้ และ จัดเก็บคีย์สาธารณะของพาสคีย์ไว้ในเซิร์ฟเวอร์ ตัวอย่างโค้ดต่อไปนี้แสดงวิธีจัดรูปแบบคำขอ JSON เมื่อสร้างพาสคีย์

บล็อกโพสต์เกี่ยวกับการนำการตรวจสอบสิทธิ์ที่ราบรื่นมาสู่แอปของคุณนี้แสดงวิธีจัดรูปแบบคำขอ JSON เมื่อสร้างพาสคีย์และเมื่อตรวจสอบสิทธิ์โดยใช้พาสคีย์ นอกจากนี้ยังอธิบายเหตุผลที่รหัสผ่านไม่ใช่โซลูชันการตรวจสอบสิทธิ์ที่มีประสิทธิภาพ วิธีใช้ประโยชน์จากข้อมูลเข้าสู่ระบบไบโอเมตริกที่มีอยู่ วิธี เชื่อมโยงแอปกับเว็บไซต์ที่คุณเป็นเจ้าของ วิธีสร้างพาสคีย์ และวิธี ตรวจสอบสิทธิ์โดยใช้พาสคีย์

{   "challenge": "abc123",   "rp": {     "name": "Credential Manager example",     "id": "credential-manager-test.example.com"   },   "user": {     "id": "def456",     "name": "[email protected]",     "displayName": "[email protected]"   },   "pubKeyCredParams": [     {       "type": "public-key",       "alg": -7     },     {       "type": "public-key",       "alg": -257     }   ],   "timeout": 1800000,   "attestation": "none",   "excludeCredentials": [     {       "id": "ghi789",       "type": "public-key"     },     {       "id": "jkl012",       "type": "public-key"     }   ],   "authenticatorSelection": {     "authenticatorAttachment": "platform",     "requireResidentKey": true,     "residentKey": "required",     "userVerification": "required"   } } 

ตั้งค่าสำหรับ authenticatorAttachment

ตั้งค่าพารามิเตอร์ authenticatorAttachment ได้ในเวลาที่สร้างข้อมูลเข้าสู่ระบบเท่านั้น คุณระบุ platform, cross-platform หรือไม่ระบุค่าก็ได้ โดยส่วนใหญ่ เราไม่แนะนำให้ระบุค่า

  • platform: หากต้องการลงทะเบียนอุปกรณ์ปัจจุบันของผู้ใช้หรือแจ้งให้ผู้ใช้ อัปเกรดเป็นพาสคีย์หลังจากลงชื่อเข้าใช้ ให้ตั้งค่า authenticatorAttachment เป็น platform
  • cross-platform: ค่านี้มักใช้เมื่อลงทะเบียนข้อมูลเข้าสู่ระบบแบบหลายปัจจัย และไม่ได้ใช้ในบริบทของพาสคีย์
  • ไม่มีค่า: เพื่อให้ผู้ใช้มีความยืดหยุ่นในการสร้างพาสคีย์ใน อุปกรณ์ที่ต้องการ (เช่น ในการตั้งค่าบัญชี) คุณไม่ควรระบุพารามิเตอร์ authenticatorAttachment เมื่อผู้ใช้เลือกที่จะเพิ่มพาสคีย์ ในกรณีส่วนใหญ่ การไม่ระบุพารามิเตอร์ เป็นตัวเลือกที่ดีที่สุด

ป้องกันการสร้างพาสคีย์ที่ซ้ำกัน

แสดงรหัสข้อมูลเข้าสู่ระบบในอาร์เรย์ excludeCredentials ที่ไม่บังคับเพื่อป้องกัน การสร้างพาสคีย์ใหม่หากมีพาสคีย์ที่มีผู้ให้บริการพาสคีย์เดียวกันอยู่แล้ว

จัดการการตอบสนองของ JSON

ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างการตอบกลับ JSON สำหรับการสร้างข้อมูลเข้าสู่ระบบคีย์สาธารณะ ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดการคีย์สาธารณะที่ส่งคืน ข้อมูลเข้าสู่ระบบ

{   "id": "KEDetxZcUfinhVi6Za5nZQ",   "type": "public-key",   "rawId": "KEDetxZcUfinhVi6Za5nZQ",   "response": {     "clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoibmhrUVhmRTU5SmI5N1Z5eU5Ka3ZEaVh1Y01Fdmx0ZHV2Y3JEbUdyT0RIWSIsIm9yaWdpbiI6ImFuZHJvaWQ6YXBrLWtleS1oYXNoOk1MTHpEdll4UTRFS1R3QzZVNlpWVnJGUXRIOEdjVi0xZDQ0NEZLOUh2YUkiLCJhbmRyb2lkUGFja2FnZU5hbWUiOiJjb20uZ29vZ2xlLmNyZWRlbnRpYWxtYW5hZ2VyLnNhbXBsZSJ9",     "attestationObject": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViUj5r_fLFhV-qdmGEwiukwD5E_5ama9g0hzXgN8thcFGRdAAAAAAAAAAAAAAAAAAAAAAAAAAAAEChA3rcWXFH4p4VYumWuZ2WlAQIDJiABIVgg4RqZaJyaC24Pf4tT-8ONIZ5_Elddf3dNotGOx81jj3siWCAWXS6Lz70hvC2g8hwoLllOwlsbYatNkO2uYFO-eJID6A"   } } 

ยืนยันต้นทางจาก JSON ของข้อมูลไคลเอ็นต์

origin แสดงถึงแอปพลิเคชันหรือเว็บไซต์ที่คำขอมาจาก และพาสคีย์ใช้เพื่อป้องกันการโจมตีแบบฟิชชิง เซิร์ฟเวอร์ของแอปต้องตรวจสอบแหล่งที่มาของข้อมูลไคลเอ็นต์กับ รายการที่อนุญาตของแอปและเว็บไซต์ที่ได้รับอนุมัติ หากเซิร์ฟเวอร์ได้รับคำขอจาก แอปหรือเว็บไซต์จากต้นทางที่ไม่รู้จัก ควรปฏิเสธคำขอ

ในกรณีของเว็บ origin จะแสดงต้นทางในเว็บไซต์เดียวกันที่ ลงชื่อเข้าใช้ข้อมูลเข้าสู่ระบบ ตัวอย่างเช่น หาก URL คือ https://www.example.com:8443/store?category=shoes#athletic origin จะเป็น https://www.example.com:8443

สำหรับแอป Android User-Agent จะตั้งค่า origin เป็นลายเซ็นของ แอปที่เรียกใช้โดยอัตโนมัติ คุณควรยืนยันลายเซ็นนี้ว่าตรงกันในเซิร์ฟเวอร์เพื่อ ตรวจสอบผู้เรียกใช้ Passkey API Android origin คือ URI ที่ได้ จากแฮช SHA-256 ของใบรับรองการลงนาม APK เช่น

android:apk-key-hash:<sha256_hash-of-apk-signing-cert> 

คุณดูแฮช SHA-256 ของใบรับรองการลงนามจากที่เก็บคีย์ได้โดย เรียกใช้คำสั่งต่อไปนี้ในเทอร์มินัล

keytool -list -keystore <path-to-apk-signing-keystore>

แฮช SHA-256 อยู่ในรูปแบบเลขฐานสิบหกที่คั่นด้วยเครื่องหมายโคลอน (91:F7:CB:F9:D6:81…) และค่า origin ของ Android จะได้รับการเข้ารหัส base64url ตัวอย่าง Python นี้แสดงวิธีแปลงรูปแบบแฮชเป็นรูปแบบเลขฐานสิบหกที่คั่นด้วยเครื่องหมายโคลอนที่เข้ากันได้

import binascii import base64 fingerprint = '91:F7:CB:F9:D6:81:53:1B:C7:A5:8F:B8:33:CC:A1:4D:AB:ED:E5:09:C5' print("android:apk-key-hash:" + base64.urlsafe_b64encode(binascii.a2b_hex(fingerprint.replace(':', ''))).decode('utf8').replace('=', '')) 

แทนที่ค่าของ fingerprint ด้วยค่าของคุณเอง ตัวอย่างผลลัพธ์ มีดังนี้

android:apk-key-hash:kffL-daBUxvHpY-4M8yhTavt5QnFEI2LsexohxrGPYU 

จากนั้นคุณจะจับคู่สตริงดังกล่าวเป็นแหล่งที่มาที่อนุญาตในเซิร์ฟเวอร์ได้ หากมีใบรับรองการลงนามหลายรายการ เช่น ใบรับรองสำหรับการแก้ไขข้อบกพร่องและการเผยแพร่ หรือมีแอปหลายรายการ ให้ทำกระบวนการซ้ำและยอมรับแหล่งที่มาทั้งหมดเหล่านั้นว่าถูกต้อง ในเซิร์ฟเวอร์

บันทึกรหัสผ่านของผู้ใช้

หากผู้ใช้ระบุชื่อผู้ใช้และรหัสผ่านสำหรับโฟลว์การตรวจสอบสิทธิ์ในแอป คุณจะลงทะเบียนข้อมูลเข้าสู่ระบบของผู้ใช้ที่ใช้ในการตรวจสอบสิทธิ์ผู้ใช้ได้ โดยสร้างออบเจ็กต์ CreatePasswordRequest ดังนี้

suspend fun registerPassword(username: String, password: String) {     // Initialize a CreatePasswordRequest object.     val createPasswordRequest =         CreatePasswordRequest(id = username, password = password)      // Create credential and handle result.     coroutineScope {         try {             val result =                 credentialManager.createCredential(                     // Use an activity based context to avoid undefined                     // system UI launching behavior.                     activityContext,                     createPasswordRequest                 )             // Handle register password result         } catch (e: CreateCredentialException) {             handleFailure(e)         }     } } 

รองรับการกู้คืนข้อมูลเข้าสู่ระบบ

หากผู้ใช้เข้าถึงอุปกรณ์ที่จัดเก็บข้อมูลเข้าสู่ระบบไม่ได้อีกต่อไป ผู้ใช้อาจต้องกู้คืนจากข้อมูลสำรองออนไลน์ที่ปลอดภัย ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีสนับสนุนกระบวนการกู้คืนข้อมูลเข้าสู่ระบบนี้ได้ที่ส่วน "การกู้คืนสิทธิ์เข้าถึงหรือการเพิ่มอุปกรณ์ใหม่" ในบล็อกโพสต์นี้ ความปลอดภัยของพาสคีย์ในเครื่องมือจัดการรหัสผ่านของ Google

สร้างพาสคีย์ให้ผู้ใช้โดยอัตโนมัติ

หากผู้ใช้ไม่มีพาสคีย์ คุณสามารถสร้างพาสคีย์ให้ผู้ใช้โดยอัตโนมัติในครั้งถัดไปที่ผู้ใช้ลงชื่อเข้าใช้โดยใช้รหัสผ่านที่บันทึกไว้ในเครื่องมือจัดการรหัสผ่าน โดยการตั้งค่าฟิลด์ isConditionalCreateRequest เมื่อขอ ข้อมูลเข้าสู่ระบบสาธารณะ

CreatePublicKeyCredentialRequest(     // other parameters     isConditionalCreateRequest: Boolean = true ) 

เมื่อผู้ใช้ลงชื่อเข้าใช้ ระบบจะสร้างพาสคีย์โดยอัตโนมัติและจัดเก็บไว้ในเครื่องมือจัดการรหัสผ่านที่ผู้ใช้เลือก หากใช้เครื่องมือจัดการรหัสผ่านบน Google ผู้ใช้ ต้องใช้รหัสผ่านที่บันทึกไว้ ในเครื่องมือจัดการรหัสผ่าน (ไม่ว่าจะใช้เครื่องมือจัดการข้อมูลเข้าสู่ระบบหรือการป้อนข้อความอัตโนมัติ) ผู้ใช้จะได้รับการแจ้งเตือนเมื่อสร้างพาสคีย์นี้ และจะไปที่เครื่องมือจัดการรหัสผ่านเพื่อจัดการพาสคีย์ได้

ฟีเจอร์นี้ต้องใช้เวอร์ชัน 1.6.0-alpha01 ขึ้นไป

เพิ่มการรองรับเครื่องมือจัดการรหัสผ่านด้วย URL ที่รู้จักกันดีของปลายทางพาสคีย์

เราขอแนะนำให้เพิ่มการรองรับ URL ที่รู้จักกันดีของปลายทางพาสคีย์เพื่อการผสานรวมที่ราบรื่นและความเข้ากันได้ในอนาคตกับเครื่องมือจัดการรหัสผ่านและข้อมูลเข้าสู่ระบบ ซึ่งเป็นโปรโตคอลแบบเปิดสำหรับฝ่ายที่เกี่ยวข้องในการโฆษณาอย่างเป็นทางการว่ารองรับพาสคีย์และระบุลิงก์โดยตรงสำหรับการลงทะเบียนและการจัดการพาสคีย์

  1. สำหรับผู้ให้บริการที่ https://example.com ซึ่งมีเว็บไซต์ รวมถึงแอป Android และ iOS URL ที่รู้จักกันดีจะเป็น https://example.com/.well-known/passkey-endpoints
  2. เมื่อมีการค้นหา URL การตอบกลับควรใช้สคีมาต่อไปนี้

    {   "enroll": "https://example.com/account/manage/passkeys/create"   "manage": "https://example.com/account/manage/passkeys" } 
  3. หากต้องการให้ลิงก์นี้เปิดในแอปโดยตรงแทนที่จะเปิดบนเว็บ ให้ใช้ลิงก์แอป Android

  4. โปรดดูรายละเอียดเพิ่มเติมในคำอธิบายURL ที่รู้จักกันดีของปลายทางพาสคีย์ ใน GitHub

ช่วยผู้ใช้จัดการพาสคีย์โดยแสดงผู้ให้บริการที่สร้างพาสคีย์

ความท้าทายอย่างหนึ่งที่ผู้ใช้พบเมื่อจัดการพาสคีย์หลายรายการที่เชื่อมโยงกับแอปหนึ่งๆ คือการระบุพาสคีย์ที่ถูกต้องเพื่อแก้ไขหรือลบ เพื่อช่วยแก้ไขปัญหานี้ เราขอแนะนำให้แอปและเว็บไซต์ระบุข้อมูลเพิ่มเติม เช่น ผู้ให้บริการที่สร้างข้อมูลเข้าสู่ระบบ วันที่สร้าง และวันที่ใช้งานล่าสุดในรายการพาสคีย์บนหน้าจอการตั้งค่าของแอป โดยระบบจะรับข้อมูลผู้ให้บริการจากการตรวจสอบ AAGUID ที่เชื่อมโยงกับพาสคีย์ที่เกี่ยวข้อง คุณดู AAGUID ได้ในส่วนข้อมูลเครื่องมือตรวจสอบสิทธิ์ของพาสคีย์

ตัวอย่างเช่น หากผู้ใช้สร้างพาสคีย์ในอุปกรณ์ที่ใช้ Android โดยใช้ เครื่องมือจัดการรหัสผ่านบน Google ทาง RP จะได้รับ AAGUID ซึ่งมีลักษณะ ดังนี้ "ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4" ผู้ให้บริการสามารถ ใส่คำอธิบายประกอบพาสคีย์ในรายการพาสคีย์เพื่อระบุว่าสร้างขึ้นโดยใช้ เครื่องมือจัดการรหัสผ่านบน Google

หากต้องการจับคู่ AAGUID กับผู้ให้บริการพาสคีย์ RP สามารถใช้ที่เก็บ AAGUID ที่มาจากชุมชน ค้นหา AAGUID ในรายการเพื่อดูชื่อและไอคอนของผู้ให้บริการพาสคีย์

อ่านเพิ่มเติมเกี่ยวกับการผสานรวม AAGUID

แก้ไขข้อผิดพลาดที่พบบ่อย

ดูรหัสข้อผิดพลาด คำอธิบาย และข้อมูลเกี่ยวกับสาเหตุของข้อผิดพลาดที่พบบ่อยได้ในคู่มือการแก้ปัญหาตัวจัดการข้อมูลเข้าสู่ระบบ

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับ Credential Manager API และพาสคีย์ได้จากแหล่งข้อมูลต่อไปนี้