Credential Manager - Verifier API

การยืนยันข้อมูลเข้าสู่ระบบดิจิทัลภายในแอป Android สามารถใช้เพื่อตรวจสอบสิทธิ์ และให้สิทธิ์ตัวตนของผู้ใช้ (เช่น บัตรประจำตัวประชาชน) คุณสมบัติเกี่ยวกับ ผู้ใช้รายนั้น (เช่น ใบขับขี่ วุฒิการศึกษา หรือแอตทริบิวต์ เช่น อายุหรือ ที่อยู่) หรือสถานการณ์อื่นๆ ที่ต้องออกและยืนยันข้อมูลเข้าสู่ระบบ เพื่อยืนยันความถูกต้องของเอนทิตี

การรับรองทางดิจิทัลเป็นมาตรฐานสาธารณะของ W3C ที่ระบุวิธีเข้าถึง การรับรองทางดิจิทัลที่ตรวจสอบได้ของผู้ใช้จากกระเป๋าเงินดิจิทัล และมีการนำไปใช้ สำหรับกรณีการใช้งานบนเว็บด้วย W3C Credential Management API ใน Android ระบบจะใช้ API DigitalCredential ของ Credential Manager เพื่อ ยืนยันข้อมูลเข้าสู่ระบบดิจิทัล

ความเข้ากันได้กับเวอร์ชัน Android

API ของเครื่องมือตรวจสอบใช้ได้ใน Android 9 (API ระดับ 28) ขึ้นไป

การใช้งาน

หากต้องการยืนยันข้อมูลประจำตัวดิจิทัลในโปรเจ็กต์ Android ให้ทำดังนี้

  1. เพิ่มทรัพยากร Dependency ลงในสคริปต์บิลด์ของแอปและเริ่มต้นคลาส CredentialManager
  2. สร้างคำขอการรับรองทางดิจิทัลและใช้เพื่อเริ่มต้น DigitalCredentialOption จากนั้นสร้าง GetCredentialRequest
  3. เปิดใช้โฟลว์ getCredential ด้วยคำขอที่สร้างขึ้นเพื่อรับ GetCredentialResponse ที่สำเร็จหรือจัดการข้อยกเว้นที่อาจเกิดขึ้น เมื่อดึงข้อมูลสำเร็จแล้ว ให้ตรวจสอบการตอบกลับ

เพิ่มการอ้างอิงและเริ่มต้น

เพิ่มทรัพยากร Dependency ต่อไปนี้ลงในสคริปต์บิลด์ Gradle

dependencies {
    implementation("androidx.credentials:credentials:1.6.0-beta01")
    implementation("androidx.credentials:credentials-play-services-auth:1.6.0-beta01")
}

จากนั้นเริ่มต้นอินสแตนซ์ของคลาส CredentialManager

val credentialManager = CredentialManager.create(context)

สร้างคำขอหนังสือรับรองดิจิทัล

สร้างคำขอการรับรองทางดิจิทัลและใช้เพื่อเริ่มต้นDigitalCredentialOption

// The request in the JSON format to conform with
// the JSON-ified Credential Manager - Verifier API request definition.
val requestJson = generateRequestFromServer()
val digitalCredentialOption =
    GetDigitalCredentialOption(requestJson = requestJson)

// Use the option from the previous step to build the `GetCredentialRequest`.
val getCredRequest = GetCredentialRequest(
    listOf(digitalCredentialOption)
)

ตัวอย่างคำขอ OpenId4Vp มีดังนี้ ดูข้อมูลอ้างอิงทั้งหมดได้ที่เว็บไซต์นี้

{
  "requests": [
    {
      "protocol": "openid4vp-v1-unsigned",
      "data": {
        "response_type": "vp_token",
        "response_mode": "dc_api",
        "nonce": "OD8eP8BYfr0zyhgq4QCVEGN3m7C1Ht_No9H5fG5KJFk",
        "dcql_query": {
          "credentials": [
            {
              "id": "cred1",
              "format": "mso_mdoc",
              "meta": {
                "doctype_value": "org.iso.18013.5.1.mDL"
              },
              "claims": [
                {
                  "path": [
                    "org.iso.18013.5.1",
                    "family_name"
                  ]
                },
                {
                  "path": [
                    "org.iso.18013.5.1",
                    "given_name"
                  ]
                },
                {
                  "path": [
                    "org.iso.18013.5.1",
                    "age_over_21"
                  ]
                }
              ]
            }
          ]
        }
      }
    }
  ]
}

รับข้อมูลเข้าสู่ระบบ

เปิดใช้โฟลว์ getCredential ด้วยคำขอที่สร้างขึ้น คุณจะได้รับGetCredentialResponseหากดำเนินการสำเร็จ หรือGetCredentialExceptionหากคำขอไม่สำเร็จ

getCredential โฟลว์จะทริกเกอร์กล่องโต้ตอบของระบบ Android เพื่อแสดงตัวเลือกข้อมูลเข้าสู่ระบบที่ใช้ได้ของผู้ใช้ และรวบรวมตัวเลือกที่ผู้ใช้เลือก จากนั้นแอปกระเป๋าเงิน ที่มีตัวเลือกข้อมูลเข้าสู่ระบบที่เลือกจะแสดง UI เพื่อรวบรวมความยินยอม และดำเนินการที่จำเป็นในการสร้างการตอบกลับของข้อมูลเข้าสู่ระบบดิจิทัล

coroutineScope.launch {
    try {
        val result = credentialManager.getCredential(
            context = activityContext,
            request = getCredRequest
        )
        verifyResult(result)
    } catch (e : GetCredentialException) {
        handleFailure(e)
    }
}

// Handle the successfully returned credential.
fun verifyResult(result: GetCredentialResponse) {
    val credential = result.credential
    when (credential) {
        is DigitalCredential -> {
            val responseJson = credential.credentialJson
            validateResponseOnServer(responseJson)
        }
        else -> {
            // Catch any unrecognized credential type here.
            Log.e(TAG, "Unexpected type of credential ${credential.type}")
        }
    }
}

// Handle failure.
fun handleFailure(e: GetCredentialException) {
  when (e) {
        is GetCredentialCancellationException -> {
            // The user intentionally canceled the operation and chose not
            // to share the credential.
        }
        is GetCredentialInterruptedException -> {
            // Retry-able error. Consider retrying the call.
        }
        is NoCredentialException -> {
            // No credential was available.
        }
        is CreateCredentialUnknownException -> {
            // An unknown, usually unexpected, error has occurred. Check the
            // message error for any additional debugging information.
        }
        is CreateCredentialCustomException -> {
            // You have encountered a custom error thrown by the wallet.
            // If you made 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}")
    }
}