इस गाइड में, OpenID for Verifiable Presentations (OpenID4VP) अनुरोध के ज़रिए, Digital Credentials Verifier API का इस्तेमाल करके, पुष्टि किए गए ईमेल पते को वापस पाने का तरीका बताया गया है.
डिपेंडेंसी जोड़ें
अपने ऐप्लिकेशन की build.gradle फ़ाइल में, Credential Manager के लिए ये डिपेंडेंसी जोड़ें:
Kotlin
dependencies { implementation("androidx.credentials:credentials:1.7.0-alpha01") implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha01") }
Groovy
dependencies { implementation "androidx.credentials:credentials:1.7.0-alpha01" implementation "androidx.credentials:credentials-play-services-auth:1.7.0-alpha01" }
Credential Manager को शुरू करना
CredentialManager ऑब्जेक्ट बनाने के लिए, अपने ऐप्लिकेशन या गतिविधि के कॉन्टेक्स्ट का इस्तेमाल करें.
// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)
डिजिटल क्रेडेंशियल का अनुरोध तैयार करना
पुष्टि किए गए ईमेल का अनुरोध करने के लिए, GetCredentialRequest बनाएं. इसमें GetDigitalCredentialOption शामिल होना चाहिए. इस विकल्प के लिए, requestJson
स्ट्रिंग की ज़रूरत होती है. इसे OpenID for Verifiable Presentations (OpenID4VP) अनुरोध के तौर पर फ़ॉर्मैट किया जाता है.
OpenID4VP अनुरोध JSON को किसी खास स्ट्रक्चर के मुताबिक होना चाहिए. फ़िलहाल, ये कंपनियां JSON स्ट्रक्चर के साथ काम करती हैं. इसमें "digital": {"requests":
[...]} रैपर शामिल होता है.
val nonce = generateSecureRandomNonce()
// This request follows the OpenID4VP spec
val openId4vpRequest = """
{
"requests": [
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "$nonce",
"dcql_query": {
"credentials": [
{
"id": "user_info_query",
"format": "dc+sd-jwt",
"meta": {
"vct_values": ["UserInfoCredential"]
},
"claims": [
{"path": ["email"]},
{"path": ["name"]},
{"path": ["given_name"]},
{"path": ["family_name"]},
{"path": ["picture"]},
{"path": ["hd"]},
{"path": ["email_verified"]}
]
}
]
}
}
}
]
}
"""
val getDigitalCredentialOption = GetDigitalCredentialOption(requestJson = openId4vpRequest)
val request = GetCredentialRequest(listOf(getDigitalCredentialOption))
अनुरोध में यह मुख्य जानकारी शामिल होती है:
DCQL क्वेरी:
dcql_queryक्रेडेंशियल टाइप और अनुरोध किए जा रहे दावों (email_verified) के बारे में बताता है. पुष्टि के लेवल का पता लगाने के लिए, अन्य दावों का अनुरोध किया जा सकता है. यहां कुछ संभावित दावे दिए गए हैं:email_verified: जवाब में, यह एक बूलियन वैल्यू होती है. इससे पता चलता है कि ईमेल की पुष्टि हुई है या नहीं.hd(होस्ट किया गया डोमेन): जवाब में यह खाली है.
अगर ईमेल पता @gmail.com नहीं है, तो Google ने Google खाता बनाते समय इस ईमेल पते की पुष्टि की थी. हालांकि, इस बात की पुष्टि नहीं की गई है कि यह ईमेल पता अब भी चालू है. इसलिए, Google से बाहर के ईमेल पतों के लिए, आपको उपयोगकर्ता की पुष्टि करने के लिए कोई और तरीका इस्तेमाल करना चाहिए. जैसे, ओटीपी. क्रेडेंशियल के स्कीमा और
email_verifiedजैसे फ़ील्ड की पुष्टि करने के लिए खास नियमों को समझने के लिए, Google Identity गाइड देखें.nonce: हर अनुरोध के लिए, क्रिप्टोग्राफ़िक तरीके से सुरक्षित एक यूनीक रैंडम वैल्यू जनरेट की जाती है. यह सुरक्षा के लिए ज़रूरी है, क्योंकि इससे रीप्ले अटैक को रोका जा सकता है.
UserInfoCredential: इस वैल्यू का मतलब है कि यह एक खास तरह का डिजिटल क्रेडेंशियल है, जिसमें उपयोगकर्ता के एट्रिब्यूट शामिल होते हैं. अनुरोध में इसे शामिल करना ज़रूरी है, ताकि ईमेल पते की पुष्टि करने के इस्तेमाल के उदाहरण को अलग किया जा सके.
इसके बाद, openId4vpRequest JSON को GetDigitalCredentialOption में रैप करें, GetCredentialRequest बनाएं, और getCredential() को कॉल करें.
उपयोगकर्ता को अनुरोध दिखाएं
क्रेडेंशियल मैनेजर के पहले से मौजूद यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करके, उपयोगकर्ता को अनुरोध दिखाएं.
try {
// Requesting Digital Credential from user...
val result = credentialManager.getCredential(activity, request)
when (val credential = result.credential) {
is DigitalCredential -> {
val responseJsonString = credential.credentialJson
// Successfully received digital credential response.
// Next, parse this response and send it to your server.
// ...
}
else -> {
// handle Unexpected State() - Up to the developer
}
}
} catch (e: Exception) {
// handle exceptions - Up to the developer
}
क्लाइंट पर जवाब को पार्स करना
जवाब मिलने के बाद, क्लाइंट पर शुरुआती पार्सिंग की जा सकती है. यह यूज़र इंटरफ़ेस (यूआई) को तुरंत अपडेट करने के लिए काम आता है. उदाहरण के लिए, उपयोगकर्ता का नाम दिखाने के लिए.
नीचे दिए गए कोड में, Selective Disclosure JWT (SD-JWT) को एक्सट्रैक्ट किया गया है. साथ ही, इसके दावों को डिकोड करने के लिए हेल्पर का इस्तेमाल किया गया है.
// 1. Parse the outer JSON wrapper to get the `vp_token`
val responseData = JSONObject(responseJsonString)
val vpToken = responseData.getJSONObject("vp_token")
// 2. Extract the raw SD-JWT string
val credentialId = vpToken.keys().next()
val rawSdJwt = vpToken.getJSONArray(credentialId).getString(0)
// 3. Use your parser to get the verified claims
// Server-side validation/parsing is highly recommended.
// Assumes a local parser like the one in our SdJwtParser.kt sample
val claims = SdJwtParser.parse(rawSdJwt)
Log.d("TAG", "Parsed Claims: ${claims.toString(2)}")
// 4. Create your VerifiedUserInfo object with REAL data
val userInfo = VerifiedUserInfo(
email = claims.getString("email"),
displayName = claims.optString("name", claims.getString("email"))
)
जवाब मैनेज करना
Credential Manager API, DigitalCredential रिस्पॉन्स देगा.
यहां responseJsonString का एक उदाहरण दिया गया है. साथ ही, इसमें बताया गया है कि अंदरूनी एसडी-जेडब्ल्यूटी को पार्स करने के बाद, दावे कैसे दिखते हैं. इसमें आपको पुष्टि किए गए ईमेल के साथ-साथ अतिरिक्त मेटाडेटा भी मिलता है:
/*
// Example of the raw JSON response from credential.credentialJson:
{
"vp_token": {
// This key matches the 'id' you set in your dcql_query
"user_info_query": [
// The SD-JWT string (Issuer JWT ~ Disclosures ~ Key Binding JWT)
"eyJhbGciOiJ...~WyI...IiwgImVtYWlsIiwgInVzZXJAZXhhbXBsZS5jb20iXQ~...~eyJhbGciOiJ..."
]
}
}
// Example of the parsed and verified claims from the SD-JWT on your server:
{
"cnf": {
"jwk": {..}
},
"exp": 1775688222,
"iat": 1775083422,
"iss": "https://verifiablecredentials-pa.googleapis.com",
"vct": "UserInfoCredential",
"email": "[email protected]",
"email_verified": true,
"given_name": "Jane",
"family_name": "Doe",
"name": "Jane Doe",
"picture": "http://example.com/janedoe/me.jpg",
"hd": ""
}
*/
खाता बनाने के लिए सर्वर-साइड से होने वाली पुष्टि
पुनः हासिल किए गए ईमेल की क्रिप्टोग्राफ़िक तरीके से पुष्टि की जाती है. इसलिए, आपको ईमेल पते के ओटीपी की पुष्टि करने के चरण को छोड़ने का विकल्प मिलता है. इससे साइन-अप करने में आने वाली मुश्किलों को काफ़ी हद तक कम किया जा सकता है. साथ ही, कन्वर्ज़न को बढ़ाया जा सकता है. इस प्रोसेस को आपके सर्वर पर सबसे बेहतर तरीके से मैनेज किया जा सकता है. क्लाइंट, vp_token और ओरिजनल नॉन्स वाला रॉ रिस्पॉन्स, नए सर्वर एंडपॉइंट को भेजता है.
पुष्टि के लिए, आपके ऐप्लिकेशन को पूरा responseJsonString आपके सर्वर पर भेजना होगा. ऐसा खाता बनाने या उपयोगकर्ता को लॉग इन करने से पहले, क्रिप्टोग्राफ़िक पुष्टि के लिए करना होगा.
डिजिटल क्रेडेंशियल, आपके सर्वर के लिए पुष्टि के दो ज़रूरी लेवल उपलब्ध कराता है:
- डेटा की पुष्टि करना:
issयूआरएल औरSD-JWTहस्ताक्षर की पुष्टि करने से यह साबित होता है कि इस डेटा को किसी भरोसेमंद संस्था ने जारी किया है. - प्रस्तुत करने वाले की पहचान:
cnfफ़ील्ड और कुंजी बाइंडिंग (kb) के हस्ताक्षर की पुष्टि करने से यह पता चलता है कि क्रेडेंशियल को उसी डिवाइस से शेयर किया जा रहा है जिस पर इसे मूल रूप से जारी किया गया था. इससे क्रेडेंशियल को इंटरसेप्ट होने या किसी दूसरे डिवाइस पर इस्तेमाल होने से रोका जा सकता है.
सर्वर पर पुष्टि करने की प्रोसेस में ये काम होने चाहिए:
- जारी करने वाले की पुष्टि करें: पक्का करें कि
iss(जारी करने वाला) फ़ील्ड,https://verifiablecredentials-pa.googleapis.comसे मेल खाता हो. - हस्ताक्षर की पुष्टि करें: SD-JWT के हस्ताक्षर की जांच करने के लिए, https://verifiablecredentials-pa.googleapis.com/.well-known/vc-public-jwks पर उपलब्ध सार्वजनिक पासकोड (JWK) का इस्तेमाल करें.
पूरी सुरक्षा के लिए, पक्का करें कि आपने nonce की पुष्टि भी की हो, ताकि रीप्ले हमलों को रोका जा सके.
इन चरणों को एक साथ पूरा करने से, आपका सर्वर डेटा की पुष्टि कर सकता है. साथ ही, यह भी पुष्टि कर सकता है कि डेटा भेजने वाला व्यक्ति कौन है. इससे यह पक्का किया जा सकता है कि नया खाता उपलब्ध कराने से पहले, क्रेडेंशियल को इंटरसेप्ट या स्पूफ़ नहीं किया गया था.
try {
// Send the raw credential response and the original nonce to your server.
// Your server must validate the response. createAccountWithVerifiedCredentials
// is a custom implementation per each RP for server side verification and account creation.
val serverResponse = createAccountWithVerifiedCredentials(responseJsonString, nonce)
// Server returns the new account info (e.g., email, name)
val claims = JSONObject(serverResponse.json)
val userInfo = VerifiedUserInfo(
email = claims.getString("email"),
displayName = claims.optString("name", claims.getString("email"))
)
// handle response - Up to the developer
} catch (e: Exception) {
// handle exceptions - Up to the developer
}
पासकी बनाना
खाता उपलब्ध कराने के बाद, हमारा सुझाव है कि आप तुरंत उस खाते के लिए पासकी बनाएं. यह ज़रूरी नहीं है, लेकिन हमारा सुझाव है कि आप ऐसा करें. इससे उपयोगकर्ता को बिना पासवर्ड के सुरक्षित तरीके से साइन इन करने का विकल्प मिलता है. यह फ़्लो, पासकी के स्टैंडर्ड रजिस्ट्रेशन जैसा ही है.
WebView के साथ काम करता है
WebView पर फ़्लो को काम करने के लिए, डेवलपर को JavaScript ब्रिज (जेएस ब्रिज) लागू करना चाहिए, ताकि हैंडऑफ़ की प्रोसेस को आसान बनाया जा सके. इस ब्रिज की मदद से, Webview, नेटिव ऐप्लिकेशन को सिग्नल भेज सकता है. इसके बाद, नेटिव ऐप्लिकेशन, Credential Manager API को कॉल कर सकता है.