Credential Manager - Verifier API

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

اعتبارنامه‌های دیجیتال یک استاندارد عمومی W3C است که نحوه دسترسی به اعتبارنامه‌های دیجیتال قابل تأیید کاربر از یک کیف پول دیجیتال را مشخص می‌کند و برای موارد استفاده وب با API مدیریت اعتبارنامه W3C پیاده‌سازی شده است. در اندروید، API اعتبارنامه DigitalCredential مدیر اعتبارنامه برای تأیید اعتبارنامه‌های دیجیتال استفاده می‌شود.

سازگاری با نسخه اندروید

رابط برنامه‌نویسی کاربردی تأییدکننده (Verifier API) در اندروید ۹ (سطح API 28) و بالاتر پشتیبانی می‌شود.

پیاده‌سازی

برای تأیید اعتبارنامه‌های دیجیتال در پروژه اندروید خود، موارد زیر را انجام دهید:

  1. وابستگی‌ها را به اسکریپت ساخت برنامه خود اضافه کنید و یک کلاس CredentialManager را مقداردهی اولیه کنید.
  2. یک درخواست اعتبارنامه دیجیتال بسازید و از آن برای مقداردهی اولیه DigitalCredentialOption استفاده کنید و به دنبال آن GetCredentialRequest بسازید.
  3. جریان getCredential را با درخواست ساخته‌شده راه‌اندازی کنید تا یک GetCredentialResponse موفق دریافت کنید یا هرگونه استثنایی را که ممکن است رخ دهد، مدیریت کنید. پس از بازیابی موفقیت‌آمیز، پاسخ را اعتبارسنجی کنید.

وابستگی‌ها را اضافه کنید و مقداردهی اولیه کنید

وابستگی‌های زیر را به اسکریپت ساخت 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 پنجره‌های محاوره‌ای سیستم اندروید را فعال می‌کند تا گزینه‌های موجود برای اعتبارنامه کاربر را ارائه داده و انتخاب‌های او را جمع‌آوری کند. در مرحله بعد، برنامه کیف پول که حاوی گزینه اعتبارنامه انتخاب شده است، رابط‌های کاربری را برای جمع‌آوری رضایت و انجام اقدامات لازم برای تولید پاسخ اعتبارنامه دیجیتال نمایش می‌دهد.

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