Bu kılavuzda, WebView kullanan bir Android uygulamasında Kimlik Bilgisi Yöneticisi'ni kullanarak dijital kimlik bilgilerinin nasıl isteneceğini açıklanmaktadır. Web sayfası ile uygulama arasındaki iletişimi kolaylaştırmak için JavaScript köprüsü kullanın.
Genel Bakış
Aşağıdaki adımlarda, bir WebView'dan gelen dijital kimlik bilgisi isteğinin yaşam döngüsü açıklanmaktadır:
- İstek oluşturma: Web görünümündeki web sayfası, uygulama sunucusuna istek gönderir. Uygulama sunucusu, OpenID4VP istek JSON'u oluşturur ve geri gönderir.
- İstek başlatma: Web sayfası, istek JSON'unu kullanarak dijital kimlik bilgileri istemek için
navigator.credentials.get({ digital: ...}) kullanır. - Müdahale: Eklenen
bridge.jsbu çağrıya müdahale eder, belirli OpenID4VP istek JSON'unu çıkarır ve Android uygulamasına iletir. - Android İşleme: Android uygulaması mesajı alır ve
CredentialManager.getCredentialAPI'sini çağırır. - Kullanıcı seçimi: Kimlik Bilgisi Yöneticisi, kullanıcıdan kimlik bilgilerini paylaşmasını isteyen bir kullanıcı arayüzü gösterir. Kimlik bilgisi Android uygulamasına döndürülür.
- Köprü yanıtı: Android uygulaması, köprüyü kullanarak yanıtı web sayfasına geri gönderir.
- Tamamlama: Web sayfası yanıtı alır ve işler.
Ön koşullar
WebView'da dijital kimlik bilgileri için JavaScript köprüsünü uygulamadan önce projenizin aşağıdaki koşulları karşıladığından emin olun:
- Android sürümü uyumluluğu: Uygulamanız Android 6.0 (API düzeyi 23) veya sonraki sürümleri hedeflemelidir.
- Ana uygulama kontrolü: Web sayfasını yüklemeden önce
WebMessageListenerekleyebilmek içinWebViewbarındıran Android uygulamasını kontrol etmeniz gerekir. - HTTPS ve üst düzey çerçeve: Kimlik bilgisi isteyen web sayfası
https://üzerinden sunulmalı ve ana çerçevede çalıştırılmalıdır (isMainFrame,trueolmalıdır). Alt çerçeveler ve yerleştirilmiş<iframe>öğeleri desteklenmez. - Deneysel API'yi etkinleştirme: Dijital Kimlik Bilgileri API'si deneysel olduğundan,
GetDigitalCredentialOptionkullanan sınıflara veya yöntemlere@OptIn(ExperimentalDigitalCredentialApi::class)ile ek açıklama eklemeniz gerekir.
Bağımlılık ekleme
Kimlik Bilgisi Yöneticisi ve AndroidX WebKit bağımlılıklarını uygulama modülünüzün build.gradle.kts dosyasına ekleyin:
dependencies {
// Credential Manager dependencies
implementation("androidx.credentials:credentials:1.7.0-alpha03")
implementation("androidx.credentials:credentials-play-services-auth:1.7.0-alpha03")
// AndroidX WebKit (required for WebMessageListener bridge)
implementation("androidx.webkit:webkit:1.14.0")
}
WebView'da dijital kimlik bilgilerini uygulama
Kimlik bilgisi isteğinde bulunmak ve bridge.js ile isteği yakalamak için WebView'unuza JavaScript eklemeniz gerekir.
JavaScript isteğini oluşturma
WebView'da çalışan JavaScript ile Android kodu arasında iletişim kurmak için WebView'unuza JavaScript kodu ekleyin:
// Example digital credential request to request verified email
const request = {
"providers": [
{
"protocol": "openid4vp",
"request": JSON.stringify({
"requests": [
{
"protocol": "openid4vp-v1-unsigned",
"data": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "n-0S6_W_2F", // Generate dynamically
"dcql_query": {
"credentials": [
{
"id": "user_info_query",
"format": "dc+sd-jwt",
"meta": {
"vct_values": ["UserInfoCredential"]
},
"claims": [
{"path": ["email"]},
{"path": ["email_verified"]},
{"path": ["name"]}
]
}
]
}
}
}
]
})
}
]
};
try {
const credential = await navigator.credentials.get({
digital: request
});
// Process response
} catch (err) {
// Handle error
}
JavaScript köprüsünü oluşturma
bridge.js adlı bir dosya oluşturun veya evaluateJavascript kullanarak bu kodu ekleyin.
Bu komut dosyası, isteği yakalamak ve dahili OpenID4VP JSON dizesini Android uygulamasına göndermek için navigator.credentials.get değerini geçersiz kılar.
(function() {
if (!navigator.credentials) {
navigator.credentials = {};
}
const originalGet = navigator.credentials.get;
// Overrides navigator.credentials.get() to intercept W3C Digital Credential requests.
navigator.credentials.get = async function(options) {
if (options && options.digital) {
if (window.DigitalCredentialBridge) {
return new Promise((resolve, reject) => {
const digital = options.digital;
if (digital.providers && digital.providers.length > 0) {
const provider = digital.providers[0];
if (provider.protocol === "openid4vp") {
const requestJson = provider.request;
const message = {
type: "get",
request: requestJson
};
console.log("Sending message to native bridge:", JSON.stringify(message));
// Send the request string to native Android code
window.DigitalCredentialBridge.postMessage(JSON.stringify(message));
// Receive the response sent from native code using replyProxy.postMessage()
window.DigitalCredentialBridge.onmessage = function(event) {
console.log("Received response from native bridge:", event.data);
try {
const response = JSON.parse(event.data);
if (response.error) {
reject(new Error(response.error));
} else {
resolve(response);
}
} catch (e) {
// If it's not JSON, just resolve with the raw data
resolve(event.data);
}
};
} else {
reject(new Error("Unsupported protocol: " + provider.protocol));
}
} else {
reject(new Error("No providers specified in digital credential request"));
}
});
} else {
console.warn("DigitalCredentialBridge not found, falling back to original");
}
}
if (originalGet) {
return originalGet.call(navigator.credentials, options);
} else {
throw new Error("navigator.credentials.get is not supported and no bridge available");
}
};
})();
Android'de dijital kimlik bilgilerini uygulama
Android uygulamanızı, bridge.js tarafından gönderilen kimlik bilgisi isteklerini işleyecek şekilde yapılandırın.
Android dinleyicisini oluşturma
WebViewCompat.WebMessageListener uygulayan bir DigitalCredentialWebListener sınıfı oluşturun. Bu sınıf, JavaScript ile yerel Android kodu arasındaki çift yönlü mesajları işler, isMainFrame ve sourceOrigin üzerinde güvenlik kontrolleri uygular ve çakışan istekleri önler.
Kimlik Bilgisi Yöneticisi İşleyici'yi uygulama
Cihazdan dijital kimlik bilgileri istemek için getCredential yöntemini çağırın.
@OptIn(ExperimentalDigitalCredentialApi::class)
class CredentialManagerHandler(private val context: Context) {
private val credentialManager = CredentialManager.create(context)
suspend fun getDigitalCredential(requestJson: String): String {
val digitalCredentialOption = GetDigitalCredentialOption(requestJson)
val getCredRequest = GetCredentialRequest(listOf(digitalCredentialOption))
return try {
val result = credentialManager.getCredential(context, getCredRequest)
val credential = result.credential
if (credential is DigitalCredential) {
credential.credentialJson
} else {
"{\"error\": \"Unexpected credential type\"}"
}
} catch (e: GetCredentialException) {
"{\"error\": \"${e.message}\"}"
} catch (e: Exception) {
"{\"error\": \"Unknown exception\"}"
}
}
companion object {
private const val TAG = "CredManHandler"
}
}
Çerçeveyi Activity kitaplığınıza uygulama
Activity veya View uygulamanızda WebMessageListener ve ilişkili işlevleri kaydedin.
// Inside your Activity or View setup
AndroidView(
factory = { context ->
val handler = CredentialManagerHandler(context)
WebView(context).apply {
settings.javaScriptEnabled = true
// Register the bridge before loading URL
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)) {
val listener = DigitalCredentialWebListener(coroutineScope, credentialManagerHandler)
WebViewCompat.addWebMessageListener(
webView,
INTERFACE_NAME,
setOf("*"),
listener
)
loadUrl("https://your-secure-domain.com/login")
}
},
)
Akış test ediliyor
WebView ile Android uygulaması arasındaki iletişimi onaylamak için akışı test edin. İşlem sırasında WebView'da kimlik bilgisi seçici görünür ve seçilen kimlik bilgisi, işlem tamamlandığında WebView'a geri döner.