PC için Play Integrity'yi uygulamanıza entegre etme

PC için Play Integrity, oyun etkinliklerinin ve sunucu isteklerinin orijinal bir PC cihazında PC için Google Play Games'in orijinal bir örneğinden gelip gelmediğini kontrol etmenizi sağlar. Oyununuzun arka uç sunucusu, riskli olabilecek cihazları ve bilinmeyen emülatörleri tespit ederek hile, yetkisiz erişim, sahte trafik ve kötüye kullanımı önlemek için uygun işlemleri yaparak yanıt verebilir.

Ön koşullar

1. adım: Oyununuzda PC için Play Integrity'yi nasıl kullanacağınıza karar verin

Ortamla ilgili bütünlük kararı almak için PC'de Play Integrity'yi ne zaman arayacağınıza karar verin. Örneğin, oyun açıldığında, bir oyuncu oturum açtığında veya bir oyuncu çok oyunculu bir oyuna katıldığında karar isteğinde bulunabilirsiniz. Ardından, farklı bütünlük yanıtlarını nasıl ele alacağınıza karar verin. Örneğin, şunları yapabilirsiniz:

  • Yanıtı herhangi bir yaptırım işlemi uygulamadan toplayın ve kötüye kullanımın yararlı bir sinyali olup olmadığını anlamak için verileri dahili olarak analiz edin.
  • Yanıtı toplayın ve arka uç sunucunuzda, bütünlük kararlarını geçen cihazların oyununuzu normal şekilde oynamasına izin verecek, şüpheli ortamlardan gelen trafiğe ise erişimi engelleyecek veya bu trafiğe meydan okuyacak mantık uygulayın.
  • Yanıtı toplayın ve arka uçunuzda, bütünlük kontrollerini geçen cihazlardaki oyuncuları eşleştirmek için mantık uygulayın. Şüpheli ortamlardan gelen trafiği de birlikte eşleştirin.

2. adım: Oyununuzda bütünlük jetonları isteyin

PC'de Play Integrity'yi etkinleştirme

Google Play'in, bir bütünlük değerlendirmesi isteğinde bulunduğunuzda kritik yoldaki gecikmeyi azaltmak için cihazda kısmi onay bilgilerini akıllıca önbelleğe almasına olanak tanıyan Play Integrity for PC'yi hazırlayın (veya "ısıtın"). Bunu, oyununuz açılır açılmaz eşzamansız olarak yapabilirsiniz. Böylece, ihtiyaç duyduğunuzda isteğe bağlı bütünlük istekleri gönderebilirsiniz.

void PrepareIntegrityToken(
  const PrepareIntegrityTokenParams & params,
  PrepareIntegrityTokenContinuation continuation
)

İşlem başarılı olduğunda devam işlemi, bir bütünlük kodu istemek için kullanılması gereken bir RequestTokenData içeren PrepareIntegrityTokenResultValue ile çağrılır. Bu veriler bellekte önbelleğe alınmalı ve RequestIntegrityToken çağrıları için uygulamanın oturum süresi boyunca yeniden kullanılmalıdır.

Yalnızca uygulamanız bütünlük değerlendirmesinin tamamen yeniden değerlendirilmesinin gerekli olduğuna karar verirse PrepareIntegrityToken çağrısı yapılmalıdır.

Ayrıntılar
Parametreler params: Google Cloud proje numarası içeren parametreler.
continuation: Bütünlük jetonu sağlayıcıyı döndürecek eş zamansız geri çağırma.

PrepareIntegrityToken işleminin nasıl çağrılması gerektiğini gösteren bir kod snippet'i aşağıda verilmiştir:

google::play::integrity::IntegrityClient client_;

google::play::integrity::PrepareIntegrityTokenResult
IntegrityInterface::PrepareIntegrityToken(int64_t cloud_project_number) {
  google::play::integrity::PrepareIntegrityTokenParams params;
  params.cloud_project_number = cloud_project_number;

  auto promise = std::make_shared<
      std::promise<google::play::integrity::PrepareIntegrityTokenResult>>();
  client_.PrepareIntegrityToken(
      params,
      [promise](
          google::play::integrity::PrepareIntegrityTokenResult result) {
        promise->set_value(std::move(result));
      });

  return promise->get_future().get();
}

Bütünlük jetonunuzu isteme

Bütünlük jetonları, oyununuzun cihazda oynama yapılmadığını doğrulamasını sağlayan bir mekanizmadır. Oyununuz, gerçekliğini kontrol etmek istediğiniz bir sunucu isteğinde bulunduğunda bütünlük jetonu isteyebilir, ardından şifre çözme ve doğrulama için oyununuzun arka uç sunucusuna gönderebilirsiniz.

Uygulamanızdaki bir kullanıcı işlemini Play Integrity API for PC ile kontrol ederken izinsiz değişiklik saldırılarını azaltmak için RequestIntegrityTokenParams::request_hash alanını kullanabilirsiniz. Örneğin, oyuncunun puanını oyununuzun arka uç sunucusuna bildirmek isteyebilirsiniz ve sunucunuz bu puanın bir proxy sunucusu tarafından değiştirilmediğini doğrulamak ister. PC için Play Integrity, imzalı bütünlük yanıtında bu alanda ayarladığınız değeri döndürebilir. requestHash olmadan bütünlük jetonu yalnızca cihaza bağlanır ancak belirli bir isteğe bağlanmaz. Bu da saldırı olasılığını artırır.

void RequestIntegrityToken(
  const RequestIntegrityTokenParams & params,
  RequestIntegrityTokenContinuation continuation
)

Saldırı olasılığını azaltmak için entegrasyon kararı istediğinizde:

  • Kullanıcı işleminden veya gerçekleşen sunucu isteğinden tüm alakalı istek parametrelerinin (ör. sabit bir istek serileştirmesinin SHA256'sı) özetini hesaplayın.
  • RequestIntegrityTokenParams::request_hash alanını özet olarak ayarlayın.
Ayrıntılar
Parametreler params: Hazırlanan RequestTokenData ve bütünlük kontrolü isteği karmasını içeren parametreler.
continuation: Verileri döndürmek için kullanılan eş zamansız geri çağırma.

RequestIntegrityToken işleminin nasıl çağrılabileceğini gösteren bir kod snippet'i aşağıda verilmiştir:

absl::StatusOr<google::play::integrity::RequestIntegrityTokenResult>
IntegrityInterface::RequestIntegrityToken(
    const google::play::integrity::PrepareIntegrityTokenResult&
        prepare_integrity_token_result,
    const std::string& request_hash) {
  // Check if the prepare_integrity_token_result is OK
  if (!prepare_integrity_token_result.ok()) {
    return absl::FailedPreconditionError(
        absl::StrCat("PrepareIntegrityTokenResult is not OK. Error code: ",
                     prepare_integrity_token_result.error_code));
  }

  google::play::integrity::RequestIntegrityTokenParams params{
      .request_token_data =
          prepare_integrity_token_result.request_token_data,
      .request_hash = request_hash};

  auto promise = std::make_shared<std::promise<
      google::play::integrity::RequestIntegrityTokenResult>>();
  client_.RequestIntegrityToken(
      params,
      [promise](google::play::integrity::RequestIntegrityTokenResult result) {
        promise->set_value(std::move(result));
      });

  return promise->get_future().get();
}

3. adım: Ardından, oyununuzun arka uç sunucusunda bütünlük jetonlarının şifresini çözün ve doğrulayın

Bütünlük jetonunun şifresini çözme

Bütünlük değerlendirmesi istedikten sonra Play Integrity API şifrelenmiş bir yanıt jetonu sağlar. Cihaz bütünlüğü kararlarını almak için Google'ın sunucularında bütünlük jetonunun şifresini çözmeniz gerekir:

  1. Uygulamanıza bağlı Google Cloud projesinde bir hizmet hesabı oluşturun.
  2. Uygulamanızın sunucusunda, playintegrity kapsamını kullanarak hizmet hesabı kimlik bilgilerinizden erişim jetonunu getirin ve şu isteği gönderin:

    playintegrity.googleapis.com/v1/<var>PACKAGE_NAME</var>:decodePcIntegrityToken -d \
     '{ "integrity_token": "<var>INTEGRITY_TOKEN</var>" }'
    
  3. JSON yanıtını okuyun.

Elde edilen yük, geliştirici tarafından sağlanan bilgilerin yanı sıra bütünlük değerlendirmelerini ve ayrıntıları içeren düz metin biçiminde bir jetondur. Şifresi çözülmüş bir bütünlük jetonu aşağıdaki gibi görünür:

{
  "requestDetails": {
    "requestPackageName": "com.your.package.name",
    "requestTime": "2025-08-29T13:10:37.285Z",
    "requestHash": "your_request_hash_string"
  },
  "deviceIntegrity": {
    "deviceRecognitionVerdict": [
      "MEETS_PC_INTEGRITY"
    ]
  },
}

Bütünlük jetonunu doğrulama

Kod çözümü yapılmış bütünlük jetonunun requestDetails alanında, geliştirici tarafından requestHash alanında sağlanan bilgiler de dahil olmak üzere istekle ilgili bilgiler yer alır.

requestHash ve packageName alanları, orijinal isteğin alanlarıyla eşleşmelidir. Bu nedenle, aşağıdaki kod snippet'inde gösterildiği gibi, requestDetails ve requestHash öğelerinin orijinal istekte gönderilenlerle eşleştiğinden emin olarak JSON yükünün requestDetails bölümünü doğrulayın:requestPackageName

const auto& request_details = json_payload["requestDetails"];

if (request_details.value("requestPackageName", "") != <YOUR_PACKAGE_NAME>) {
  // Don't trust the verdicts.
}

// Check for the existence of the request_hash.
// If you set a request hash in the request and it's not present, you shouldn't
// trust the verdicts.
if (!request_details.contains("requestHash")) {
    // Don't trust the verdicts.
}


// The requestHash from request_details needs to match the request hash your
// app provided.
if (request_details.value("requestHash", "") != <PROVIDED_REQUEST_HASH>) {
    // Don't trust the verdicts.
}

// You can read the rest of payload's fields.

4. adım: Entegrasyon kararına göre hangi işlemi yapacağınıza karar verin

deviceIntegrity alanı tek bir değer içerebilir: deviceRecognitionVerdict. Bu değeri, oyununuzun Play bütünlük denetimlerini geçen bir PC'de (MEETS_PC_INTEGRITY yanıtı) çalışıp çalışmadığını belirlemek için kullanabilirsiniz. Oyununuzun arka uç sunucusu bu bilgileri toplayabilir ve oyununuzun hangi işlemi yapması gerektiğine karar vermek için kullanabilir. Örneğin, bir oyun etkinliğinin devam etmesine izin verebilir veya riskli trafiğe erişimi engelleyebilir.

"deviceIntegrity": {
  "deviceRecognitionVerdict": ["MEETS_PC_INTEGRITY"]
}

deviceRecognitionVerdict aşağıdaki değerleri alabilir:

MEETS_PC_INTEGRITY
Oyun, cihazda herhangi bir kurcalama tespit edilmeyen orijinal bir PC ortamında çalıştırılıyor.
Boş (boş değer)
Oyunun çalıştığı cihazda saldırı (API kancalama gibi) veya sistem bozulması (ör. cihazda değiştirilmiş bir Google Masaüstü Hizmetleri sürümünün çalıştırılması) belirtileri var ya da uygulama fiziksel bir cihazda çalışmıyor (ör. Google Play bütünlük kontrollerini geçmeyen bir emülatörde çalışıyor).

5. adım: Hata kodlarını düzeltin

Oyununuz PC için Play Integrity isteğinde bulunur ve çağrı başarısız olursa oyununuz bir hata kodu alır. Bu hatalar, zayıf ağ bağlantısı gibi çevresel sorunlar, API entegrasyonunuzla ilgili problemler veya kötü amaçlı etkinlikler ve aktif saldırılar gibi çeşitli nedenlerle oluşabilir.

Yeniden denenebilir hata kodları

Bu hataların nedeni bazen geçici koşullardan kaynaklanır. Bu nedenle, eksponansiyel geri yükleme stratejisiyle aramayı yeniden denemeniz gerekir.

IntegrityError Hata Açıklaması Hata Kodu
kNetworkError Cihazda ağ bağlantısı sorunu. 5
kTooManyRequests Cihazdan çok fazla istek gönderildi. 6
kClientTransientError İstemciyle ilgili geçici bir sorun. 7

Yeniden deneme stratejileri hakkında daha fazla öneri için burayı inceleyin.

Yeniden denenemeyen hata kodları

Bu durumlarda otomatik yeniden denemelerin yardımcı olması beklenmez. Ancak kullanıcı, soruna neden olan koşulu düzeltirse manuel yeniden deneme yardımcı olabilir.

IntegrityError Hata Açıklaması Hata Kodu Önerilen işlem
kError SDK işlemi sırasında önemli hata oluştu. 1 Yeniden denemeden önce API uygulamanızı doğrulayın.
kCloudProjectNumberIsInvalid Cloud projesi numarası geçersiz. 2 Google Cloud Console'da bulut projesi numaranızın doğru şekilde yapılandırıldığını ve isteklerin doğru bulut projesi numarasıyla yapıldığını doğrulayın.
kRequestHashTooLong İstek karması çok uzun. 3 Oluşturulan istek karmaları çok uzun. 500 karakterden kısa olduğundan emin olun.
kNoValidPreparedTokenFound Jeton isteğinde bulunmadan önce hazırlanmış bir jeton yoktur. 4 [RequestIntegrityToken][request-integrity-token] çağrısını yapmadan önce [PrepareIntegrityToken][prepare-token] işlemini çağırın.
kSdkRuntimeUpdateRequired Play for Native SDK'nın güncellenmesi gerekir. 8 Cihazdaki Google Play Hizmetleri istemcisinin güncel olduğundan ve Play for Native PC SDK'nın en yeni sürümünü kullandığınızdan emin olun.