Search code examples
c#google-apigoogle-api-dotnet-client

How to get a decoded Play Integrity API token using the Google Client API for .NET


I am trying to use the Google.Apis.PlayIntegrity.v1 namespace of the Google Client API library for .NET to decode an integrity token, as recommended in the Play Integrity API documentation.

However, it is unclear from the library documentation how to do this. It seems that the decoded token payload is supposed to be returned from a DecodeIntegrityTokenResponse object, yet I can't find any method that returns this type.

I would expect that this type would be returned from DecodeIntegrityToken(DecodeIntegrityTokenRequest, String) but this method actually returns another DecodeIntegrityTokenRequest, which doesn't help at all.

Is anyone successfully using this library to decode the token?

References:

Attempted Code:

String integrityToken = "...token...";

String serviceAccountEmail = "...service account email...";

var certificate = new X509Certificate2("...key.p12...", "...secret...");

ServiceAccountCredential credential = new ServiceAccountCredential(
     new ServiceAccountCredential.Initializer(serviceAccountEmail)
     {
             Scopes = new[] { PlayIntegrityService.Scope.Playintegrity }
     }.FromCertificate(certificate));

// Create the service.
var service = new PlayIntegrityService(new BaseClientService.Initializer()
{
        HttpClientInitializer = credential,
        ApplicationName = "Play Integrity API Sample",
});

DecodeIntegrityTokenRequest request = new     DecodeIntegrityTokenRequest();
request.IntegrityToken = integrityToken;
DecodeIntegrityTokenResponse response = service.V1.DecodeIntegrityToken(request, "...package name...");

Error CS0029 Cannot implicitly convert type 'Google.Apis.PlayIntegrity.v1.V1Resource.DecodeIntegrityTokenRequest' to 'Google.Apis.PlayIntegrity.v1.Data.DecodeIntegrityTokenResponse'


Solution

  • You should rely on your ide to tell you what types these objects are

    Your code says that the method DecodeIntegrityToken should return a DecodeIntegrityTokenResponse. You are declaring it as such instead of using var and allowing the compiler to figure it out for you.

    DecodeIntegrityTokenResponse response = service.V1.DecodeIntegrityToken(request, "...package name...");
    

    Your problem is that this method actually returns a DecodeIntegrityTokenRequest.

    enter image description here

    To get a DecodeIntegrityTokenResponse you need to execute the request

    var request = service.V1.DecodeIntegrityToken(requestBody, "...package name...");
    var result = request.Execute();
    

    Full code cleanup

    using System.Security.Cryptography.X509Certificates;
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.PlayIntegrity.v1;
    using Google.Apis.PlayIntegrity.v1.Data;
    using Google.Apis.Services;
    
    Console.WriteLine("Hello, World!");
    
    
    var integrityToken = "...token...";
    
    var serviceAccountEmail = "...service account email...";
    var pathToCert = "...key.p12...";
    var certPassword = "...secret...";
    var packageName = "...package name...";
    
    var certificate = new X509Certificate2(pathToCert, certPassword);
    
    var credential = new ServiceAccountCredential(
        new ServiceAccountCredential.Initializer(serviceAccountEmail)
        {
            Scopes = new[] { PlayIntegrityService.Scope.Playintegrity }
        }.FromCertificate(certificate));
    
    // Create the service.
    var service = new PlayIntegrityService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = "Play Integrity API Sample",
    });
    
    var requestBody = new DecodeIntegrityTokenRequest
    {
        IntegrityToken = integrityToken
    };
    var request = service.V1.DecodeIntegrityToken(requestBody, packageName);
    
    var result = request.Execute();