使用 Google Play Developer API 进行服务器端授权?
Posted
技术标签:
【中文标题】使用 Google Play Developer API 进行服务器端授权?【英文标题】:Server side authorization with Google Play Developer API? 【发布时间】:2018-06-18 23:02:42 【问题描述】:从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。
是否有一种简洁的方法可以使用一些 API 更轻松地/以编程方式处理 OAuth2.0 以访问 Google Play Developer API?否则我必须手动实现。
【问题讨论】:
这是一个非常广泛的问题。 @jpaugh 不,不是。我确信解决方案是一些 API 类的组合。任何我想我不是唯一一个有这个问题的人。 对库推荐或示例代码的请求都被视为离题。询问如何使用 API 可以成为话题。 【参考方案1】:在经历了很多头痛之后(就像总是使用 Google API 和服务一样),我想出了如何使用现有 API 访问 Google Play Developer API 信息(例如计费)。
1.) 在开发人员 API 控制台中创建服务帐户 (JSON) 密钥:
2.) 下载此 service-account-private-key.json 文件(不要将其与 OAuth2.0 客户端机密文件混淆!)。
3.) 在 Google Play 开发者控制台中转到 Settings -> Users & Permissions -> Invite New User
并将下载文件中的 client_email 设置为新用户的用户电子邮件。通过此视图中的复选框(例如“查看财务数据”)分配您要授予此用户的访问权限。
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;
【讨论】:
我们是否应该在将 json 文件的内容存储在某个位置时对其进行加密,否则我发现任何可以访问它的人都可以轻松读取它。我在想内容应该存储在一个加密文件中,当我们阅读时,我们应该解密它然后提供它。 @africandrogba 不一定。服务器将从一个特殊用户开始,该用户是唯一对该文件具有读取权限的用户。 (权限 rwx --- ---)。只有这个用户和 root 可以读取这个文件,如果有人获得 root 访问权限,那么无论如何都会丢失。 AndroidPublisher 发布者 = new AndroidPublisher.Builder(WebserverConfiguration.HTTP_TRANSPORT, WebserverConfiguration.JSON_FACTORY, WebserverConfiguration.getCredential()).setApplicationName(String.valueOf(R.string.app_name)).build();在此行中获取空点异常@Bevor @MuntasirAonik 你甚至没有说什么是空的,所以我回答这个问题的信息太少了。【参考方案2】:在 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;
【讨论】:
我无法使用“clientId”实例化 GoogleAuthorizationCodeFlow,但在https://developers.google.com/api-client-library/java/google-api-java-client/oauth2
的下一步中,他们会说'This flow is implemented using GoogleAuthorizationCodeFlow. The steps are: End-user logs in to your application. You will need to associate that user with a user ID that is unique for your application.
- 这个“用户 ID”让我感到困惑。首先,我认为这是 GoogleID(当用户使用 Google 登录时获得)但也许我错了,这是我可以分配的一些随机代码。会试试的。
添加了官方示例的链接,希望它们比我之前的答案解释得更好。
这似乎很有帮助。我将尝试通过这些示例找到解决方案。以上是关于使用 Google Play Developer API 进行服务器端授权?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Google Play Developer API 取消发布应用
Google Play Developer API - 超出配额
获取访问令牌Google Play Android Developer API
获取访问令牌 Google Play Android Developer API