Server side authorization with Google Play Developer API?

我的梦境 提交于 2019-12-19 03:40:08

问题


Authorization is required to fetch information from the Google Play Developer API.

I know how to do this with Postman, but implementing authorization is much more cumbersome (redirect url, handling redirects, and so on...) These would be the steps when you already have setup the auth data inside the Google Developer API Console.

1.) GET https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=http://www.myurl.com/oauth2callback&client_id=1234567890.apps.googleusercontent.com
2.) get code which was sent to redirect url. 
3.) POST https://accounts.google.com/o/oauth2/token
with
    grant_type:authorization_code
    code:[the code I got before]
    client_id:1234567890.apps.googleusercontent.com
    client_secret:[my client secret]
4.) Invoke GET https://www.googleapis.com/androidpublisher/v2/applications/packageName/purchases/subscriptions/subscriptionId/tokens/token
with:
  Scope: https://www.googleapis.com/auth/androidpublisher
and:
  access_token as query parameter I got before.

Now I want to do all this programmatically. Obviously not so easy. I thought the Google API Client Libraries will help, but I don't see, how these lib can help me with my use case.
For example classes like GoogleAuthorizationCodeFlow expect a user id at the moment of the request, but I not necessarily have one at this moment, so I wonder how this API should be used in a clean way.

Is there a clean way to handle OAuth2.0 easier / programmatically with some API to access Google Play Developer API? Otherwise I must implement it manually.


回答1:


After lots of headache (like always with Google APIs and services) I figured out how one can access Google Play Developer API information (like billing) by using existing APIs.

1.) Create in Developer API Console a service account (JSON) key:

2.) Download this service-account-private-key.json file (don't mistake it with the OAuth2.0 client secret file!).

3.) In Google Play Developer Console go to Settings -> Users & Permissions -> Invite New User and set as user e-mail of the new user the client_email from the downloaded file. Assign the access rights you want to give to this users via the checkboxes inside this view (for example 'View financial data').

4.) Add the proper dependency to your project (version ...-1.23.0 does not work for me):

<dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-androidpublisher</artifactId>
    <version>v2-rev50-1.22.0</version>
</dependency>

5.) Load the service-account-private-key.json file into your application. In my case it's a webserver:

@Singleton
@Startup
public class WebserverConfiguration
{
    private String serviceAccountPrivateKeyFilePath;

    /** Global instance of the HTTP transport. */
    public static HttpTransport HTTP_TRANSPORT;

    /** Global instance of the JSON factory. */
    public static JsonFactory JSON_FACTORY;

    private GoogleCredential credential;

    @PostConstruct
    public void init()
    {
        assignServiceAccountFileProperty();
        initGoogleCredentials();
    }

    public String getServiceAccountPrivateKeyFilePath()
    {
        return serviceAccountPrivateKeyFilePath;
    }

    public GoogleCredential getCredential()
    {
        return credential;
    }

    private void initGoogleCredentials()
    {
        try
        {
            newTrustedTransport();
            newJsonFactory();

            String serviceAccountContent = new String(Files.readAllBytes(Paths.get(getServiceAccountPrivateKeyFilePath())));
            InputStream inputStream = new ByteArrayInputStream(serviceAccountContent.getBytes());

            credential = GoogleCredential.fromStream(inputStream).createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));

        }
        catch (IOException | GeneralSecurityException e)
        {
            throw new InitializationException(e);
        }
    }

    private void newJsonFactory()
    {
        JSON_FACTORY = JacksonFactory.getDefaultInstance();
    }

    private void assignServiceAccountFileProperty()
    {
        serviceAccountPrivateKeyFilePath = System.getProperty("service.account.file.path");
        if (serviceAccountPrivateKeyFilePath == null)
        {
            throw new IllegalArgumentException("service.account.file.path UNKNOWN - configure it as VM startup parameter in Wildfly");
        }
    }

    private static void newTrustedTransport() throws GeneralSecurityException, IOException
    {
        if (HTTP_TRANSPORT == null)
        {
            HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        }
    }
}

6.) Now I am able the fetch Google Play Developer API information, e.g. reviews:

private void invokeGoogleApi() throws IOException
{       
    AndroidPublisher publisher = new AndroidPublisher.Builder(WebserverConfiguration.HTTP_TRANSPORT, WebserverConfiguration.JSON_FACTORY, configuration.getCredential()).setApplicationName("The name of my app on Google Play").build();
    AndroidPublisher.Reviews reviews = publisher.reviews();
    ReviewsListResponse reviewsListResponse = reviews.list("the.packagename.of.my.app").execute();
    logger.info("review list response = " + reviewsListResponse.toPrettyString());
}

This worked.

I cannot test it yet, but I'm sure that fetching the billing information works as well:

private SubscriptionPurchase getPurchase() throws IOException
{
    AndroidPublisher publisher = new AndroidPublisher.Builder(WebserverConfiguration.HTTP_TRANSPORT, WebserverConfiguration.JSON_FACTORY, configuration.getCredential()).setApplicationName("The name of my app on Google Play").build();
    AndroidPublisher.Purchases purchases = publisher.purchases();

    SubscriptionPurchase purchase = purchases.subscriptions().get("the.packagename.of.my.app", "subscriptionId", "billing token sent by the app").execute();

    //do something or return
    return purchase;
}



回答2:


There are complete code samples and documentation for doing this in Java here

In the Java source code this authorizes like this

private static Credential authorizeWithServiceAccount(String serviceAccountEmail)
            throws GeneralSecurityException, IOException {
        log.info(String.format("Authorizing using Service Account: %s", serviceAccountEmail));

        // Build service account credential.
        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setServiceAccountId(serviceAccountEmail)
                .setServiceAccountScopes(
                        Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER))
                .setServiceAccountPrivateKeyFromP12File(new File(SRC_RESOURCES_KEY_P12))
                .build();
        return credential;
    }


来源:https://stackoverflow.com/questions/48176187/server-side-authorization-with-google-play-developer-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!