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. Quá trình này bao gồm hai bước:
- Kiểm tra trước: Kiểm tra xem nhà mạng của người dùng có hỗ trợ API này hay không bằng cách truy vấn API Điện thoại Android. Nếu nhà mạng không được hỗ trợ, hãy quay lại quy trình SMS thông thường.
- Yêu cầu
TS.43 token: Ứng dụng khách ("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 cấp, đại diện cho danh tính của người dùng. - Đổi mã thông báo lấy số điện thoại: Phần phụ trợ của ứng dụng sẽ đổi
TS.43 tokenvới một công ty 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ó tài khoản với một công ty tổng hợp hoặc nhà mạng di động. Một 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í. Trong hướng dẫn này, cả công ty tổng hợp và nhà mạng đều được gọi chung là công ty tổng hợp.
Bạn cũng cần thêm các phần phụ thuộc sau vào tập lệnh bản 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
Trước khi gọi Digital Credentials API, hãy kiểm tra xem nhà mạng của người dùng có hỗ trợ tính năng này hay không bằng cách sử dụng Android Telephony API.
Thêm quyền READ_PHONE_STATE vào tệp AndroidManifest.xml.
val telephonyManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val carrierId = telephonyManager.getSimCarrierId()
Hãy dùng mã nhận dạng này để xác minh khả năng hỗ trợ TS.43 với phần phụ trợ của bên tổng hợp. Nếu nhà mạng của người dùng này không được hỗ trợ, thì bạn có thể quay lại một phương thức thay thế như SMS, vì việc gọi Digital Credentials API sẽ trả về kết quả trống. Nếu không, hãy tiếp tục với quy trình Giấy tờ tuỳ thân kỹ thuật số.
Quy trình toàn diện thường bao gồm các bước sau:
- Yêu cầu tham số DCQL (Ngôn ngữ truy vấn thông tin xác thực kỹ thuật số) từ một bên tổng hợp: Gọi một hoặc nhiều bên 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 thêm các tham số DCQL từ trình tổng hợp. Sau đó, hãy gửi yêu cầu OpenID4VP đến ứng dụng khách.
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ằng trình tổng hợp 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.
Đổ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. Công ty tổng hợp 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ừ mộ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 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 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 một đố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 trong một đối tượng dcql_query như 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 một yêu cầu OpenID4VP có cấu trúc như 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 có giá trị cố định lần lượt làvp_tokenvàdc_api.nonce: Giá trị riêng biệt do phần phụ trợ của bạn tạo cho mỗi yêu cầu. Giá trị 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 giá trị dùng một lần này.dcql_query: Trong trường hợp này, hãy sử dụngdcql_queryđể chỉ định rằngTS.43 Digital Credentialđang được yêu cầu. 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 đó, gói yêu cầu OpenID4VP trong một đối tượng yêu cầu DigitalCredential API 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à tệp JSON thông tin xác thực thông thường từ kết quả DigitalCredential:
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"vp_token": {
"aggregator1": ["eyJhbGciOiAiRVMy..."] # The encrypted TS.43 Digital
# Credential in an array structure.
}
}
}
Trong ứ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ợ, nơi phản hồi này có thể được xác thực và dùng để trao đổi số điện thoại đã xác minh với một công ty tổng hợp.
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 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ể có:
invalid_request: Mã này cho biết yêu cầu không đúng định dạng.server_error: Cho biết đã 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êm thông tin chi tiết về vấn đề.
Xác thực phản hồi của Giấy tờ tuỳ thân 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.
Đổ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)