คู่มือนี้จะอธิบายรายละเอียดวิธีใช้ DigitalCredential API เพื่อรับหมายเลขโทรศัพท์ที่ยืนยันแล้ว สำหรับผู้ใช้ กระบวนการนี้มี 2 ขั้นตอนดังนี้
- ขอ
TS.43 token
: แอปไคลเอ็นต์ ("เครื่องมือยืนยัน") ขอโทเค็น TS.43 ชั่วคราวจากอุปกรณ์ของผู้ใช้TS.43 token
คือ ข้อมูลเข้าสู่ระบบที่ผู้ให้บริการออกให้ซึ่งแสดงถึงตัวตนของผู้ใช้ - แลกเปลี่ยนโทเค็นเป็นหมายเลขโทรศัพท์: Backend ของแอปจะแลกเปลี่ยน
TS.43 token
กับผู้รวบรวมข้อมูลหรือผู้ให้บริการเพื่อรับหมายเลขโทรศัพท์ที่ยืนยันแล้วของผู้ใช้
สิ่งที่ต้องมีก่อน
หากต้องการใช้การยืนยันหมายเลขโทรศัพท์ด้วย DigitalCredential API คุณต้องมี บัญชีกับผู้รวบรวมข้อมูล ผู้รวบรวมจะโต้ตอบกับผู้ให้บริการขนส่งและ จัดเตรียม API ที่จำเป็นสำหรับแอปของคุณ โดยปกติจะเป็นปลายทาง API ของระบบคลาวด์ที่เรียกเก็บเงินได้
นอกจากนี้ คุณยังต้องเพิ่มทรัพยากร Dependency ต่อไปนี้ลงในสคริปต์การสร้าง Gradle ด้วย
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.6.0-alpha05") implementation("androidx.credentials:credentials-play-services-auth:1.6.0-alpha05") }
ดึงดูด
dependencies { implementation "androidx.credentials:credentials:1.6.0-alpha05" implementation "androidx.credentials:credentials-play-services-auth:1.6.0-alpha05" }
การใช้งาน
โดยทั่วไปกระบวนการตั้งแต่ต้นจนจบจะมีขั้นตอนดังนี้
- ขอพารามิเตอร์ DCQL (ภาษาการค้นหาข้อมูลประจำตัวดิจิทัล) จาก ผู้รวบรวมข้อมูล: โทรหาผู้รวบรวมข้อมูลอย่างน้อย 1 รายและขอชุดพารามิเตอร์ DCQL DCQL ช่วยให้คุณระบุข้อมูลเข้าสู่ระบบดิจิทัลที่แน่นอนซึ่งคุณต้องการจากผู้รวบรวมแต่ละรายได้
สร้างคำขอ OpenID4VP: สร้างคำขอ OpenID4VP จากแบ็กเอนด์ของแอป พร้อมทั้งใส่พารามิเตอร์ DCQL จากผู้รวบรวม จากนั้นส่งคำขอ OpenID4VP ไปยังแอปไคลเอ็นต์
เรียกใช้ Credential Manager API: ในแอปไคลเอ็นต์ ให้ใช้ Credential Manager API เพื่อส่งคำขอ OpenID4VP ไปยังระบบปฏิบัติการ ในการตอบกลับ คุณจะได้รับออบเจ็กต์การตอบกลับ OpenID4VP ที่มี
TS.43 Digital Credential
ระบบจะเข้ารหัสข้อมูลเข้าสู่ระบบนี้และมีเพียงผู้รวบรวมข้อมูลที่เชื่อมโยงเท่านั้นที่ ถอดรหัสได้ หลังจากได้รับโทเค็นของผู้ให้บริการขนส่งแล้ว ให้ส่งการตอบกลับจากแอปไคลเอ็นต์ไปยังแบ็กเอนด์ของแอปตรวจสอบการตอบกลับ: ตรวจสอบการตอบกลับ OpenID4VP ในแบ็กเอนด์ของแอป
แลกเปลี่ยนเป็นหมายเลขโทรศัพท์: จากแบ็กเอนด์ของแอป ให้ส่ง
TS.43 Digital Credential
ไปยังผู้รวบรวมข้อมูล ผู้รวบรวมจะตรวจสอบความถูกต้องของ ข้อมูลเข้าสู่ระบบและแสดงหมายเลขโทรศัพท์ที่ยืนยันแล้ว
ขอพารามิเตอร์ DCQL จากผู้รวบรวมข้อมูล
จากแบ็กเอนด์ของแอป ให้ส่งคำขอไปยังผู้รวบรวมเพื่อขอออบเจ็กต์ข้อมูลเข้าสู่ระบบ Digital Credential Query Language (DCQL) โปรดระบุ Nonce และรหัสคำขอในคำขอ ผู้รวบรวมจะแสดงผลออบเจ็กต์ข้อมูลเข้าสู่ระบบ DCQL ซึ่งมีโครงสร้างคล้ายกับต่อไปนี้
{
// 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"]
}
]
}
สร้างคำขอ OpenID4VP
ก่อนอื่น ให้สร้างออบเจ็กต์ dcql_query
จากแบ็กเอนด์ของแอปโดยวางออบเจ็กต์ข้อมูลเข้าสู่ระบบ DCQL
ไว้ในอาร์เรย์ credentials
ที่ซ้อนอยู่ในออบเจ็กต์ dcql_query
ดังที่แสดงในตัวอย่างต่อไปนี้
"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"]
}
]
]
}
จากนั้นสร้างคำขอ OpenID4VP ที่มีโครงสร้างต่อไปนี้
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
protocol
: ต้องตั้งค่าเป็นopenid4vp-v1-unsigned
สำหรับคำขอการยืนยันหมายเลขโทรศัพท์response_type
และresponse_mode
: ค่าคงที่ที่ระบุรูปแบบของคำขอที่มีค่าคงที่vp_token
และdc_api
ตามลำดับnonce
: ค่าที่ไม่ซ้ำกันซึ่งแบ็กเอนด์สร้างขึ้นสำหรับคำขอแต่ละรายการ Nonce ในออบเจ็กต์ข้อมูลเข้าสู่ระบบ DCQL ของผู้รวบรวมต้องตรงกับ Nonce นี้dcql_query
: ในกรณีนี้ ให้ใช้dcql_query
เพื่อระบุว่ามีการขอTS.43 Digital Credential
นอกจากนี้ คุณยังขอข้อมูลเข้าสู่ระบบดิจิทัลอื่นๆ ได้ที่นี่
จากนั้นห่อหุ้มคำขอ OpenID4VP ในออบเจ็กต์คำขอ DigitalCredential API แล้ว ส่งไปยังแอปไคลเอ็นต์
{
"requests":
[
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "...",
"dcql_query": { ... }
}
}
]
}
ข้อมูลโค้ดต่อไปนี้แสดงวิธีสร้างคำขอ 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
เรียกใช้ Credential Manager API
ในแอปไคลเอ็นต์ ให้เรียกใช้ Credential Manager API โดยใช้คำขอ DigitalCredential API ที่แบ็กเอนด์ของแอปให้ไว้
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)
}
}
การตอบกลับของ DigitalCredential API มีการตอบกลับ OpenID4VP โดยทั่วไปแล้ว
ไฟล์ JSON ของข้อมูลเข้าสู่ระบบจากผลลัพธ์ของ DigitalCredential
จะมีลักษณะดังนี้
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"vp_token": {
"aggregator1": ["eyJhbGciOiAiRVMy..."] # The encrypted TS.43 Digital
# Credential in an array structure.
}
}
}
จากแอปไคลเอ็นต์ ให้ส่งการตอบกลับของ DigitalCredential API กลับไปยังเซิร์ฟเวอร์แบ็กเอนด์ ซึ่งสามารถตรวจสอบและใช้เพื่อแลกเปลี่ยนหมายเลขโทรศัพท์ที่ยืนยันแล้วกับผู้รวบรวมข้อมูลได้
ตรวจสอบการตอบกลับของเอกสารรับรองดิจิทัล
ตัวอย่างต่อไปนี้แสดงวิธีแยกวิเคราะห์การตอบกลับและทำขั้นตอนการตรวจสอบความถูกต้องในแบ็กเอนด์ของแอป
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.
แลกเปลี่ยนหมายเลขโทรศัพท์
จากแบ็กเอนด์ของแอป ให้ส่ง TS.43 Digital Credential
ที่ตรวจสอบแล้วไปยัง
ปลายทางของตัวรวบรวมเพื่อตรวจสอบข้อมูลเข้าสู่ระบบและรับหมายเลขโทรศัพท์ที่ยืนยันแล้ว
def processDigitalCredentialsResponse(response):
# ... prior steps
# Step 3: Call aggregator endpoint to exchange the verified phone number
callAggregatorPnvEndpoint(ts43_digital_credential)