Google Play Developer API 的服务器端授权?

Server side authorization with Google Play Developer API?

需要授权才能从 Google Play Developer API.

获取信息

我知道如何用 Postman 做到这一点,但是实现授权要麻烦得多(重定向 url、处理重定向等等...) 这些将是您已经在 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.

现在我想以编程方式完成所有这些工作。显然不是那么容易。我认为 Google API Client Libraries 会有所帮助,但我不明白这些库如何帮助我处理我的用例。
例如 类 就像 GoogleAuthorizationCodeFlow 在请求的时候期望一个用户 ID,但我现在不一定有,所以我想知道这个 API 应该如何在一个干净的环境中使用方式。

是否有一种干净的方法可以更轻松地/以编程方式处理 OAuth2.0,让一些 API 访问 Google Play Developer API?否则我必须手动实现它。

在 Java here

中有完整的代码示例和文档来执行此操作

Java source code这样授权

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

在经历了很多令人头疼的事情之后(就像总是使用 Google API 和服务一样)我想出了如何访问 Google Play Developer API 信息(比如账单) 通过使用现有的 APIs.

1.) 在 Developer API 控制台中创建服务帐户 (JSON) 密钥:

2.) 下载这个 service-account-private-key.json 文件(不要把它和 OAuth2.0 客户端密码文件弄错了!)。

3.) 在 Google Play Developer Console 中转到 Settings -> Users & Permissions -> Invite New User 并将 client_email[=35= 设置为新用户的用户电子邮件] 从下载的文件。通过此视图内的复选框分配您要授予此用户的访问权限(例如 'View financial data')。

4.) 将适当的依赖项添加到您的项目中(版本 ...-1.23.0 对我不起作用):

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

5.) 将 service-account-private-key.json 文件加载到您的应用程序中。在我的例子中,它是一个网络服务器:

@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.) 现在我可以获取 Google Play Developer API 信息,例如评论:

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());
}

这有效。

我还不能测试它,但我确信获取账单信息也能正常工作:

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