驗證數位憑證

Android 應用程式中的數位憑證驗證功能可用於驗證及授權使用者的身分 (例如政府身分證件)、使用者相關屬性 (例如駕照、學位,或年齡或地址等屬性),或是其他需要核發及驗證憑證的情況,以便宣告實體的真實性。

數位憑證是 公開的 W3C 孵化器標準,可指定如何從數位錢包存取使用者的可驗證數位憑證,並透過 W3C 憑證管理 API 為網路用途實作。在 Android 上,Credential Manager 的 DigitalCredential API 會用於驗證數位憑證。

實作

如要在 Android 專案中驗證數位憑證,請按照下列步驟操作:

  1. 在應用程式的建構指令碼中加入依附元件,並初始化 CredentialManager 類別。
  2. 建構數位憑證要求,並用於初始化 DigitalCredentialOption,接著建構 GetCredentialRequest
  3. 使用已建構的要求啟動 getCredential 流程,以便接收成功的 GetCredentialResponse,或處理可能發生的任何例外狀況。擷取成功後,請驗證回應。

新增依附元件並初始化

將下列依附元件新增至 Gradle 建構指令碼:

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

接著,初始化 CredentialManager 類別的例項。

val credentialManager = CredentialManager.create(context)

建構數位憑證要求

建構數位憑證要求,並用於初始化 DigitalCredentialOption

// The request in the JSON format to conform with
// the JSON-ified Digital Credentials 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)
)

取得憑證

使用建構的要求啟動 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}")
    }
}