Hướng dẫn này trình bày chi tiết cách sử dụng DigitalCredential API để lấy số điện thoại đã xác minh cho người dùng. Quy trình này gồm 2 bước:
- Yêu cầu
TS.43 token: Ứng dụng khách của bạn ("trình xác minh") yêu cầu mã thông báo TS.43 tạm thời từ thiết bị của người dùng.TS.43 tokenlà thông tin xác thực do nhà mạng phát hành, đại diện cho danh tính của người dùng. - Trao đổi mã thông báo để lấy số điện thoại: Phần phụ trợ của ứng dụng sẽ trao đổi
TS.43 tokenvới một trình tổng hợp hoặc nhà mạng để lấy số điện thoại đã xác minh của người dùng.
Khả năng tương thích với phiên bản Android
API Xác minh số điện thoại được hỗ trợ trên Android 10 (cấp độ API 29) trở lên.
Điều kiện tiên quyết
Để triển khai quy trình xác minh số điện thoại bằng DigitalCredential API, bạn cần có một tài khoản với trình tổng hợp. Trình tổng hợp tương tác với các nhà mạng và cung cấp giao diện API cần thiết cho ứng dụng của bạn, thường là điểm cuối API đám mây có tính phí.
Bạn cũng cần thêm các phần phụ thuộc sau vào tập lệnh xây dựng Gradle:
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.7.0-alpha02") implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha02") }
Groovy
dependencies { implementation "androidx.credentials:credentials:1.7.0-alpha02" implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha02" }
Triển khai
Quy trình từ đầu đến cuối thường tuân theo các bước sau:
- Yêu cầu các tham số DCQL (Ngôn ngữ truy vấn thông tin xác thực kỹ thuật số) từ trình tổng hợp: Gọi một hoặc nhiều trình tổng hợp và yêu cầu một tập hợp tham số DCQL. DCQL cho phép bạn chỉ định chính xác thông tin xác thực kỹ thuật số mà bạn cần từ mỗi trình tổng hợp.
Tạo yêu cầu OpenID4VP: Từ phần phụ trợ của ứng dụng, hãy tạo yêu cầu OpenID4VP, đồng thời đưa các tham số DCQL từ trình tổng hợp vào. Sau đó, hãy gửi yêu cầu OpenID4VP đến ứng dụng khách của bạn.
Gọi Credential Manager API: Trong ứng dụng khách, hãy dùng Credential Manager API để gửi yêu cầu OpenID4VP đến hệ điều hành. Để phản hồi, bạn sẽ nhận được một đối tượng phản hồi OpenID4VP chứa
TS.43 Digital Credential. Thông tin xác thực này được mã hoá và chỉ có thể được giải mã bởi trình tổng hợp được liên kết. Sau khi nhận được mã thông báo của nhà mạng, hãy gửi phản hồi từ ứng dụng khách đến phần phụ trợ của ứng dụng.Xác thực phản hồi: Trong phần phụ trợ của ứng dụng, hãy xác thực phản hồi OpenID4VP.
Trao đổi để lấy số điện thoại: Từ phần phụ trợ của ứng dụng, hãy gửi
TS.43 Digital Credentialđến trình tổng hợp. Trình tổng hợp sẽ xác thực thông tin xác thực và trả về số điện thoại đã xác minh.
Yêu cầu các tham số DCQL từ trình tổng hợp
Từ phần phụ trợ của ứng dụng, hãy gửi yêu cầu đến trình tổng hợp để lấy đối tượng thông tin xác thực Ngôn ngữ truy vấn thông tin xác thực kỹ thuật số (DCQL). Hãy nhớ cung cấp một số chỉ dùng một lần và mã yêu cầu trong yêu cầu của bạn. Trình tổng hợp sẽ trả về đối tượng thông tin xác thực DCQL có cấu trúc tương tự như sau:
{
// The credential ID is mapped to the request ID that is sent in your request to the aggregator.
"id": "aggregator1",
"format": "dc-authorization+sd-jwt",
"meta": {
"vct_values": [
"number-verification/device-phone-number/ts43"
],
"credential_authorization_jwt": "..."
},
"claims": [
{
"path": ["subscription_hint"],
"values": [1]
},
{
"path": ["phone_number_hint"],
"values": ["+14155552671"]
}
]
}
Tạo yêu cầu OpenID4VP
Trước tiên, từ phần phụ trợ của ứng dụng, hãy tạo đối tượng dcql_query bằng cách đặt đối tượng thông tin xác thực DCQL vào một mảng credentials lồng ghép trong đối tượng dcql_query như minh hoạ trong ví dụ sau:
"dcql_query": {
"credentials": [
"id": "aggregator1",
"format": "dc-authorization+sd-jwt",
"meta": {
"vct_values": [
"number-verification/device-phone-number/ts43"
],
"credential_authorization_jwt": "..."
},
"claims": [
{
"path": ["subscription_hint"],
"values": [1]
},
{
"path": ["phone_number_hint"],
"values": ["+14155552671"]
}
]
]
}
Sau đó, hãy tạo yêu cầu OpenID4VP có cấu trúc sau:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
protocol: Phải được đặt thànhopenid4vp-v1-unsignedcho các yêu cầu xác minh số điện thoại.response_typevàresponse_mode: Các hằng số biểu thị định dạng của yêu cầu với các giá trị cố định lần lượt làvp_tokenvàdc_api.nonce: Một giá trị duy nhất do phần phụ trợ của bạn tạo cho mỗi yêu cầu. Số chỉ dùng một lần trong đối tượng thông tin xác thực DCQL của trình tổng hợp phải khớp với số chỉ dùng một lần này.dcql_query: Trong trường hợp này, hãy dùngdcql_queryđể chỉ định rằng bạn đang yêu cầuTS.43 Digital Credential. Bạn cũng có thể yêu cầu các thông tin xác thực kỹ thuật số khác tại đây.
Sau đó, hãy gói yêu cầu OpenID4VP trong một đối tượng yêu cầu API DigitalCredential và gửi đối tượng đó đến ứng dụng khách.
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
]
}
Đoạn mã sau đây minh hoạ cách tạo yêu cầu DigitalCredential API:
def GenerateDCRequest():
credentials = []
aggregator1_dcql = call_aggregator_endpoint(nonce, "aggregator1", additional_params)
credentials.append(aggregator1_dcql) # You can optionally work with multiple
# aggregators, or request other types of credentials
val dc_request =
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": {"credentials": credentials}
}
}
]
}
return dc_request
Gọi Credential Manager API
Trong ứng dụng khách, hãy gọi Credential Manager API bằng yêu cầu API DigitalCredential do phần phụ trợ của ứng dụng cung cấp.
val requestJson = generateTs43DigitalCredentialRequestFromServer()
val digiCredOption = GetDigitalCredentialOption(requestJson = requestJson)
val getCredRequest = GetCredentialRequest(
listOf(digiCredOption)
)
coroutineScope.launch {
try {
val response = credentialManager.getCredential(
context = activityContext,
request = getCredRequest
)
val credential = response.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}")
}
}
} catch (e : GetCredentialException) {
// If user cancels the operation, the feature isn't available, or the
// SIM doesn't support the feature, a GetCredentialCancellationException
// will be returned. Otherwise, a GetCredentialUnsupportedException will
// be returned with details in the exception message.
handleFailure(e)
}
}
Phản hồi của DigitalCredential API chứa phản hồi OpenID4VP. Sau đây là một json thông tin xác thực điển hình từ kết quả DigitalCredential:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"vp_token": {
"aggregator1": ["eyJhbGciOiAiRVMy..."] # The encrypted TS.43 Digital
# Credential in an array structure.
}
}
}
Từ ứng dụng khách, hãy gửi phản hồi của DigitalCredential API trở lại máy chủ phụ trợ để xác thực và dùng để trao đổi với trình tổng hợp để lấy số điện thoại đã xác minh.
Trong một số trường hợp, phản hồi có thể chứa lỗi TS.43. Phản hồi lỗi là một đối tượng json tuân theo định dạng phản hồi lỗi OpenID4VP:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"error": "<error_code>",
"error_description": "<Human-readable description of the error>",
}
}
Có 2 giá trị error_code có thể xảy ra:
invalid_request: Cho biết rằng yêu cầu có định dạng không đúng.server_error: Cho biết rằng đã xảy ra lỗi khi xử lý yêu cầu. Đây có thể là lỗi cục bộ hoặc vấn đề về TS.43.
Trường error_description cung cấp thông tin bổ sung về vấn đề này.
Xác thực phản hồi Thông tin xác thực kỹ thuật số
Sau đây là ví dụ về cách phân tích cú pháp phản hồi và thực hiện bước xác thực trong phần phụ trợ của ứng dụng:
def processDigitalCredentialsResponse(response):
# Step 1: Parse out the TS.43 Digital Credential from the response
openId4VpResponse = response['data']
ts43_digital_credential = response['vp_token']["aggregator1"][0]
# Step 2: Perform response validation
verifyResponse(ts43_digital_credential)
def verifyResponse(ts43_digital_credential):
# The returned ts43_digital_credential is an SD-JWT-based Verifiable Credentials
# (SD-JWT VC) as defined in this IETF spec. The section 3.4 of the specification
# outlines how to validate the credential. At a high level, the steps involves
# validating (1) the nonce in the response credential matches the one in the
# request, (2) the integrity of the credential by checking the credential is
# signed by the trusted issuer Android Telephony, and (3) other validity
# properties associated with this credential, such as issue time and expiration
# time
# In most cases, you can use an SD-JWT VC library to perform these validations.
# Some aggregators may also perform the validation logic for you. Check with your
# aggregator to decide the exact scope of the validation required.
Trao đổi để lấy số điện thoại
Từ phần phụ trợ của ứng dụng, hãy gửi TS.43 Digital Credential đã xác thực đến điểm cuối của trình tổng hợp để xác thực thông tin xác thực và nhận số điện thoại đã xác minh.
def processDigitalCredentialsResponse(response):
# ... prior steps
# Step 3: Call aggregator endpoint to exchange the verified phone number
callAggregatorPnvEndpoint(ts43_digital_credential)