Bağımlılık ekleme

Uygulamanızın build.gradle dosyasına Credential Manager için aşağıdaki bağımlılıkları ekleyin:

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

Kimlik Bilgisi Yöneticisi'ni başlatma

CredentialManager nesnesi oluşturmak için uygulamanızı veya etkinlik bağlamınızı kullanın.

// Use your app or activity context to instantiate a client instance of
// CredentialManager.
private val credentialManager = CredentialManager.create(context)

Dijital kimlik bilgisi isteğini oluşturma

Doğrulanmış e-posta istemek için GetDigitalCredentialOption içeren bir GetCredentialRequest oluşturun. Bu seçenek için, OpenID4VP (Verifiable Presentations) isteği olarak biçimlendirilmiş bir requestJson dizesi gerekir.

OpenID4VP isteği JSON'u belirli bir yapıda olmalıdır. Mevcut sağlayıcılar, dış "digital": {"requests": [...]} sarmalayıcısı olan bir JSON yapısını destekler.

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

Ardından, openId4vpRequest JSON'ı GetDigitalCredentialOption içine alın, GetCredentialRequest oluşturun ve getCredential()'ü çağırın.

İsteği kullanıcıya sunma

Yerleşik Kimlik Bilgisi Yöneticisi kullanıcı arayüzünü kullanarak kullanıcıya isteği sunun.

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
}

Yanıtı istemcide ayrıştırma

Yanıtı aldıktan sonra istemcide ön ayrıştırma işlemi gerçekleştirebilirsiniz. Bu, kullanıcı adını göstermek gibi kullanıcı arayüzünü anında güncellemek için kullanışlıdır.

Aşağıdaki kod, ham Seçici Açıklama JWT'sini (SD-JWT) ayıklar ve taleplerinin kodunu çözmek için bir yardımcı kullanır.

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

Yanıtı işleme

Credential Manager API, DigitalCredential yanıtını döndürür.

Aşağıda, ham responseJsonString'nin nasıl göründüğüne ve doğrulanmış e-postanın yanı sıra ek meta veriler de aldığınız iç SD-JWT ayrıştırıldıktan sonra hak taleplerinin nasıl göründüğüne dair bir örnek verilmiştir:

/*
// 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": "jane.doe.246745@gmail.com",
  "email_verified": true,
  "given_name": "Jane",
  "family_name": "Doe",
  "name": "Jane Doe",
  "picture": "http://example.com/janedoe/me.jpg",
  "hd": ""
}
 */

Hesap oluşturma için sunucu tarafı doğrulama

Doğrulama için uygulamanız, hesap oluşturmadan veya kullanıcıyı oturum açmadan önce tam responseJsonString değerini kriptografik doğrulama için sunucunuza göndermelidir.

Sunucudaki doğrulama aşağıdaki koşulları karşılamalıdır:

  • Düzenleyeni doğrulayın: iss (düzenleyen) alanının https://verifiablecredentials-pa.googleapis.com ile eşleştiğinden emin olun.
  • İmzayı doğrulama: https://verifiablecredentials-pa.googleapis.com/.well-known/vc-public-jwks adresinde bulunan ortak anahtarları (JWK'ler) kullanarak SD-JWT'nin imzasını kontrol edin.

Tam güvenlik için, tekrar oynatma saldırılarını önlemek amacıyla nonce öğesini de doğruladığınızdan emin olun.

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
}

Hesap sağlandıktan sonra isteğe bağlı ancak önemle tavsiye edilen bir sonraki adım, bu hesap için hemen geçiş anahtarı oluşturmaktır. Bu, kullanıcının oturum açması için güvenli ve şifresiz bir yöntem sağlar. Bu akış, standart geçiş anahtarı kaydıyla aynıdır.

Akışın WebView'da çalışması için geliştiricilerin, devri kolaylaştırmak amacıyla bir JavaScript köprüsü (JS köprüsü) uygulaması gerekir. Bu köprü, WebView'ın yerel uygulamaya sinyal göndermesine olanak tanır. Yerel uygulama daha sonra Credential Manager API'ye gerçek çağrıyı gerçekleştirebilir.