【问题标题】:Unable to get the subscription information from Google Play Android Developer API无法从 Google Play Android Developer API 获取订阅信息
【发布时间】:2012-06-22 08:14:11
【问题描述】:

我正在尝试使用适用于 Java 的 Google API 客户端库来获取有关在我的 Android 应用中购买的用户订阅的信息。这是我现在的做法:

HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
JsonFactory JSON_FACTORY = new JacksonFactory();

GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
                    .setJsonFactory(JSON_FACTORY)
                    .setServiceAccountId(GOOGLE_CLIENT_MAIL)
                    .setServiceAccountScopes("https://www.googleapis.com/auth/androidpublisher")
                    .setServiceAccountPrivateKeyFromP12File(new File(GOOGLE_KEY_FILE_PATH))
                    .build();

Androidpublisher publisher = new Androidpublisher.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).
                    setApplicationName(GOOGLE_PRODUCT_NAME).
                    build();

Androidpublisher.Purchases purchases = publisher.purchases();
Get get = purchases.get("XXXXX", subscriptionId, token);
SubscriptionPurchase subscripcion = get.execute(); //Exception returned here

GOOGLE_CLIENT_MAIL 是来自 Google 控制台的 API 访问的电子邮件地址。 GOOGLE_KEY_FILE_PATH 是从 API Access 下载的 p12 文件。
GOOGLE_PRODUCT_NAME 是品牌信息中的产品名称。
在 Google APIS 控制台中,“Google Play Android Developer API”服务已启用。

我得到的是:

{
  "code" : 401,
  "errors" : [ {
    "domain" : "androidpublisher",
    "message" : "This developer account does not own the application.",
    "reason" : "developerDoesNotOwnApplication"
  } ],
  "message" : "This developer account does not own the application."
}

非常感谢您对这个问题的帮助...

【问题讨论】:

  • 我有一些疑问。我坚持了一个星期。我正在做一个应用程序来获取游戏商店的所有评论。它适用于在 Play 商店中拥有帐户的所有最终用户。 developers.google.com/android-publisher/getting_started 该文档指定我需要创建 oAuth,并且我需要在我的开发人员控制台中链接项目 ID 以访问我尝试过的审核 API,并且它工作正常。但是对于所有最终用户来说,他们创建 OAuth 并将项目 id 链接到他们的开发控制台然后访问我的应用程序我没有得到任何解决方案,如果有人知道请回复

标签: java android google-api subscription google-play


【解决方案1】:

我搞定了!我遵循的步骤:

先决条件

在开始之前,我们需要生成一个刷新令牌。为此,我们首先必须创建一个 API 控制台项目:

  1. 转到APIs Console 并使用您的 Android 开发人员登录 帐号(与Android Developer Console 中用于上传 APK 的帐号相同)。
  2. 选择创建项目。
  3. 转到左侧导航面板中的服务。
  4. 打开 Google Play Android 开发者 API
  5. 接受服务条款。
  6. 转到左侧导航面板中的 API 访问。
  7. 选择创建 OAuth 2.0 客户端 ID:
    • 在第一页,您需要填写产品名称,但 不需要徽标。
    • 在第二页,选择web application并设置redirect URI 和 Javascript 的起源。稍后我们将使用它作为重定向 URI。
  8. 选择创建客户端 ID。请记住Client IDClient secret,我们稍后会用到它们。

所以,现在我们可以生成刷新令牌了:

  1. 转到以下 URI(请注意,重定向 URI 必须与客户端 ID 中输入的值完全匹配,包括任何尾部反斜杠):

https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=REDIRECT_URI&client_id=CLIENT_ID

  1. 出现提示时选择允许访问。
  2. 浏览器将使用 code 参数重定向到您的重定向 URI,该参数类似于 4/eWdxD7b-YSQ5CNNb-c2iI83KQx19.wp6198ti5Zc7dJ3UXOl0T3aRLxQmbwI。复制此值。

创建一个主类:

public static String getRefreshToken(String code)
{

    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
    try 
    {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
        nameValuePairs.add(new BasicNameValuePair("grant_type",    "authorization_code"));
        nameValuePairs.add(new BasicNameValuePair("client_id",     GOOGLE_CLIENT_ID));
        nameValuePairs.add(new BasicNameValuePair("client_secret", GOOGLE_CLIENT_SECRET));
        nameValuePairs.add(new BasicNameValuePair("code", code));
        nameValuePairs.add(new BasicNameValuePair("redirect_uri", GOOGLE_REDIRECT_URI));
        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        org.apache.http.HttpResponse response = client.execute(post);
        BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer buffer = new StringBuffer();
        for (String line = reader.readLine(); line != null; line = reader.readLine())
        {
            buffer.append(line);
        }

        JSONObject json = new JSONObject(buffer.toString());
        String refreshToken = json.getString("refresh_token");                      
        return refreshToken;
    }
    catch (Exception e) { e.printStackTrace(); }

    return null;
}

GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETGOOGLE_REDIRECT_URI 是之前的值。

终于,我们有了刷新令牌!此值不会过期,因此我们可以存储在某个站点中,例如属性文件。

访问 Google Play Android Developer API

  1. 获取访问令牌。我们将需要我们之前的刷新令牌:

    private static String getAccessToken(String refreshToken){
    
    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
    try 
    {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
        nameValuePairs.add(new BasicNameValuePair("grant_type",    "refresh_token"));
        nameValuePairs.add(new BasicNameValuePair("client_id",     GOOGLE_CLIENT_ID));
        nameValuePairs.add(new BasicNameValuePair("client_secret", GOOGLE_CLIENT_SECRET));
        nameValuePairs.add(new BasicNameValuePair("refresh_token", refreshToken));
        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    
        org.apache.http.HttpResponse response = client.execute(post);
        BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer buffer = new StringBuffer();
        for (String line = reader.readLine(); line != null; line = reader.readLine())
        {
            buffer.append(line);
        }
    
        JSONObject json = new JSONObject(buffer.toString());
        String accessToken = json.getString("access_token");
    
        return accessToken;
    
    }
    catch (IOException e) { e.printStackTrace(); }
    
    return null;
    

    }

  2. 现在,我们可以访问 Android API。我对订阅的到期时间很感兴趣,所以:

    private static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
    private static JsonFactory JSON_FACTORY = new com.google.api.client.json.jackson2.JacksonFactory();
    
    private static Long getSubscriptionExpire(String accessToken, String refreshToken, String subscriptionId, String purchaseToken){
    
    try{
    
        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setAccessToken(accessToken);
        tokenResponse.setRefreshToken(refreshToken);
        tokenResponse.setExpiresInSeconds(3600L);
        tokenResponse.setScope("https://www.googleapis.com/auth/androidpublisher");
        tokenResponse.setTokenType("Bearer");
    
        HttpRequestInitializer credential =  new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setClientSecrets(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
                .build()
                .setFromTokenResponse(tokenResponse);
    
        Androidpublisher publisher = new Androidpublisher.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).
                setApplicationName(GOOGLE_PRODUCT_NAME).
                build();
    
        Androidpublisher.Purchases purchases = publisher.purchases();
        Get get = purchases.get(GOOGLE_PACKAGE_NAME, subscriptionId, purchaseToken);
        SubscriptionPurchase subscripcion = get.execute();
    
        return subscripcion.getValidUntilTimestampMsec();
    
    }
    catch (IOException e) { e.printStackTrace(); }
    return null;
    

    }

仅此而已!

部分步骤来自https://developers.google.com/android-publisher/authorization

【讨论】:

  • 您好,我在获取访问权限和刷新令牌时遇到问题。我已经有了代码,但是当我执行 http post 请求以检索访问或刷新令牌时,我收到了错误的请求错误 400 或“invalid_request”。
  • @Jonathan Naguin 您在调用 Google Play 购买 api 时通过了哪些访问权限?用户的访问令牌或开发人员的访问令牌,因为我正在获取此开发人员帐户不拥有应用程序错误。
  • @Searock 在getSubscriptionExpire 传递的访问令牌是来自getAccessToken 的返回值
  • 请注意,如果您使用的是 httpclient-4.2,则必须在创建 UrlEncodedFormEntity 时指定编码:post.setEntity(new UrlEncodedFormEntity(nameValuePairs, "utf-8@)); 否则会导致 NullPointerException。
  • 我觉得这个过程看起来多么迟钝很荒谬。这方面的文档实际上是不存在的。对于“帮助”库,必须通过 SO 挖掘甚至找到一个体面的代码示例是荒谬的。苹果的文档完全烂透了,但至少验证收据的过程很简单。 /咆哮
【解决方案2】:

您可以使用com.google.api-clientgoogle-api-services-androidpublisher 库。

首先在谷歌开发者控制台(https://console.developers.google.com)上进入项目

  • API 和身份验证 -> API
  • 启用“Google Play Android 开发者 API”
  • 转到凭据 -> 创建新的客户端 ID
  • 选择服务帐号
  • 创建客户端 ID
  • 将 p12 文件保存在安全的地方

然后将刚刚生成的服务帐户电子邮件地址添加到您的 google play 开发者控制台 (https://play.google.com/apps/publish/)

  • 设置 -> 用户和权限 -> 邀请新用户
  • 粘贴@developer.gserviceaccount.com 电子邮件帐户
  • 选择“查看财务报告”
  • 发送邀请

现在看代码。将以下依赖项添加到您的 pom.xml 文件中:

<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.18.0-rc</version>
</dependency>
<dependency>
    <groupId>com.google.http-client</groupId>
    <artifactId>google-http-client-jackson2</artifactId>
    <version>1.18.0-rc</version>
</dependency>
<dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-androidpublisher</artifactId>
    <version>v1.1-rev25-1.18.0-rc</version>
</dependency>

然后先验证签名:

byte[] decoded = BASE64DecoderStream.decode(KEY.getBytes());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(decoded));
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(publicKey);
sig.update(signedData.getBytes());
if (sig.verify(BASE64DecoderStream.decode(signature.getBytes())))
{
    // Valid
}

如果签名验证获取订阅详细信息:

// fetch signature details from google
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredential credential = new GoogleCredential.Builder()
    .setTransport(httpTransport)
    .setJsonFactory(jsonFactory)
    .setServiceAccountId(ACCOUNT_ID)
    .setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/androidpublisher"))
    .setServiceAccountPrivateKeyFromP12File(new File("key.p12"))
    .build();

AndroidPublisher pub = new AndroidPublisher.Builder(httpTransport, jsonFactory, credential)
    .setApplicationName(APPLICATION_NAME)
    .build();
AndroidPublisher.Purchases.Get get = pub.purchases().get(
    APPLICATION_NAME,
    PRODUCT_ID,
    token);
SubscriptionPurchase subscription = get.execute();
System.out.println(subscription.toPrettyString());

这将通过生成 JWT 令牌来处理所有令牌问题,因此您不必自己处理。

【讨论】:

  • 这看起来是一个很好的答案......但是 KEY 是从哪里来的? Google 发送给我的 JSON(不是 .p12)文件有一个 PKCS#8 格式的“private_key”(即有“-----BEGIN PRIVATE KEY-----”开始),所以我收到一个@ 987654331@ 在generatePublic() 调用期间出现“algid 解析错误,不是序列”。我尝试将X509EncodedKeySpec() 更改为PKCS8EncodedKeySpec(),但我得到了一个不同的错误:InvalidKepSpecException 带有“RSA 公钥仅支持 RSAPublicKeySpec 和 X509EncodedKeySpec”。有什么想法吗?
  • 我有一些疑问。我坚持了一个星期。我正在做一个应用程序来获取游戏商店的所有评论。它适用于在 Play 商店中拥有帐户的所有最终用户。 developers.google.com/android-publisher/getting_started 该文档指定我需要创建 oAuth,并且我需要在我的开发者控制台中链接项目 ID 以访问我尝试过的审核 API,并且它工作正常。但是对于所有最终用户来说,他们创建 OAuth 并将项目 id 链接到他们的开发控制台然后访问我的应用程序我没有得到任何解决方案,如果有人知道请回复
  • 如果有人遇到与我相同的错误,请提供一点提示:如果您在加载 .p12 文件时遇到异常,提示类似DerInputStream.getLength(): lengthTag=111, too big.,请确保将其从 Maven 过滤中排除:@ 987654324@
【解决方案3】:

对于那些想要使用 Java 在 Google 的 AppEngine 上检查订阅状态的人,这是我基于 SO 上的许多代码的工作示例。我花了几天时间解决了许多由于缺乏经验而导致的错误。我看到很多建议检查服务器上的订阅状态,但我在 AppEngine 上做起来并不容易。如果没有在 SO 上找到答案,我无法想出这个。

第 1 步

首先,我们需要浏览 Jonathan Naguin 的答案中的“先决条件”部分,直到您从网络浏览器获得 代码。现在你有了;

  • 客户 ID
  • 客户端密码
  • 重定向 URI
  • 代码

准备好了。

请注意,我们在 AppEngine 上运行下面显示的所有代码。我使用了这样的记录器。

static final Logger log = Logger.getLogger(MyClassName.class.getName());

第 2 步

我们需要获取刷新令牌。将 [YOUR CLIENT ID], [YOUR CLIENT SECRET], [YOUR CODE], [YOUR REDIRECT URI] 替换为您的字符串后运行如下所示的代码。

private String getRefreshToken()
{
    try
    {
        Map<String,Object> params = new LinkedHashMap<>();
        params.put("grant_type","authorization_code");
        params.put("client_id",[YOUR CLIENT ID]);
        params.put("client_secret",[YOUR CLIENT SECRET]);
        params.put("code",[YOUR CODE]);
        params.put("redirect_uri",[YOUR REDIRECT URI]);

        StringBuilder postData = new StringBuilder();
        for(Map.Entry<String,Object> param : params.entrySet())
        {
            if(postData.length() != 0)
            {
                postData.append('&');
            }
            postData.append(URLEncoder.encode(param.getKey(),"UTF-8"));
            postData.append('=');
            postData.append(URLEncoder.encode(String.valueOf(param.getValue()),"UTF-8"));
        }
        byte[] postDataBytes = postData.toString().getBytes("UTF-8");

        URL url = new URL("https://accounts.google.com/o/oauth2/token");
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.getOutputStream().write(postDataBytes);

        BufferedReader  reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuffer buffer = new StringBuffer();
        for (String line = reader.readLine(); line != null; line = reader.readLine())
        {
            buffer.append(line);
        }

        JSONObject json = new JSONObject(buffer.toString());
        String refreshToken = json.getString("refresh_token");
        return refreshToken;
    }
    catch (Exception ex)
    {
        log.severe("oops! " + ex.getMessage());
    }
    return null;
}

由于刷新令牌不会过期,我们可以将其保存在某处或简单地硬编码在我们的代码中。 (我们只需要运行一次以上代码即可获得刷新令牌。)

第 3 步

我们需要获取访问令牌。将 [YOUR CLIENT ID]、[YOUR CLIENT SECRET]、[YOUR REFRESH TOKEN] 替换为您的字符串后运行如下所示的代码。

private String getAccessToken()
{
    try
    {
        Map<String,Object> params = new LinkedHashMap<>();
        params.put("grant_type","refresh_token");
        params.put("client_id",[YOUR CLIENT ID]);
        params.put("client_secret",[YOUR CLIENT SECRET]);
        params.put("refresh_token",[YOUR REFRESH TOKEN]);

        StringBuilder postData = new StringBuilder();
        for(Map.Entry<String,Object> param : params.entrySet())
        {
            if(postData.length() != 0)
            {
                postData.append('&');
            }
            postData.append(URLEncoder.encode(param.getKey(),"UTF-8"));
            postData.append('=');
            postData.append(URLEncoder.encode(String.valueOf(param.getValue()),"UTF-8"));
        }
        byte[] postDataBytes = postData.toString().getBytes("UTF-8");

        URL url = new URL("https://accounts.google.com/o/oauth2/token");
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.getOutputStream().write(postDataBytes);

        BufferedReader  reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuffer buffer = new StringBuffer();
        for (String line = reader.readLine(); line != null; line = reader.readLine())
        {
            buffer.append(line);
        }

        JSONObject json = new JSONObject(buffer.toString());
        String accessToken = json.getString("access_token");
        return accessToken;
    }
    catch (Exception ex)
    {
        log.severe("oops! " + ex.getMessage());
    }
    return null;
}

第 4 步

我想知道的只是订阅的 UTC 过期时间。下面显示的代码返回过期 UTC,发现错误时返回 0。您需要提供您的包名称、产品 ID(=订阅 ID)、您在第 3 步中获得的访问令牌以及在您的购买数据中找到的购买令牌。

private long getExpireDate(String packageName,String productId,String accessToken,String purchaseToken)
{
    try
    {
        String charset = "UTF-8";
        String query = String.format("access_token=%s",URLEncoder.encode(accessToken,charset));

        String path = String.format("https://www.googleapis.com/androidpublisher/v1/applications/%s/subscriptions/%s/purchases/%s",packageName,productId,purchaseToken);
        URL url = new URL(path + "?" + query);
        HttpURLConnection connection = (HttpURLConnection)url.openConnection();
        connection.setRequestProperty("Accept-Charset",charset);
        connection.setRequestMethod("GET");

        BufferedReader  reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        StringBuffer buffer = new StringBuffer();
        for(String line = reader.readLine(); line != null; line = reader.readLine())
        {
            buffer.append(line);
        }

        JSONObject json = new JSONObject(buffer.toString());
        return json.optLong("validUntilTimestampMsec");
    }
    catch (Exception ex)
    {
        log.severe("oops! " + ex.getMessage());
    }
    return 0;
}

注意产品 ID 或订阅 ID 是在开发者控制台上找到的字符串。您的订阅项目出现在名称/id 列中。看起来像这样。

Description of item(product id)

最后一步(有趣的部分)

现在我们拥有所有组件来验证订阅是否有效。我确实喜欢这个。您需要将 [YOUR PACKAGE NAME]、[YOUR PRODUCT ID] 替换为您的。

您需要提供购买数据,您可以使用 iabHelper 代码中的 Purchase#getOriginalJson() 获取这些数据。

private boolean checkValidSubscription(String purchaseData)
{
    String purchaseToken;
    JSONObject json;
    try
    {
        json = new JSONObject(purchaseData);
    }
    catch (JSONException e)
    {
        log.severe("purchaseData is corrupted");
        return true;    // false positive
    }
    purchaseToken = json.optString("purchaseToken");
    if(purchaseToken.length() == 0)
    {
        log.severe("no purchase token found");
        return true;    // false positive
    }
    String accessToken = getAccessToken();
    if(accessToken == null)
    {
        return true;    // false positive
    }
    long expireDate = getExpireDate([YOUR PACKAGE NAME],[YOUR PRODUCT ID],accessToken,purchaseToken);
    if(expireDate == 0)
    {
        log.severe("no expire date found");
        return true;    // false positive
    }
    expireDate += 86400000l;    // add one day to avoid mis judge
    if(expireDate  < System.currentTimeMillis())
    {
        log.severe("subscription is expired");
        return false;
    }
    // just for log output
    long leftDays = (expireDate - System.currentTimeMillis()) / 86400000l;
    log.info(leftDays + " days left");
    return true;
}

调试注意事项

Google 返回 JSON 字符串作为响应。如果代码无法按预期运行,记录 JSON 字符串可能有助于了解问题所在。

我希望这对某人有所帮助。

【讨论】:

  • 我有一些疑问。我坚持了一个星期。我正在做一个应用程序来获取游戏商店的所有评论。它适用于在 Play 商店中拥有帐户的所有最终用户。 developers.google.com/android-publisher/getting_started 该文档指定我需要创建 oAuth,并且我需要在我的开发人员控制台中链接项目 ID 以访问我尝试过的审核 API,并且它工作正常。但是对于所有最终用户来说,他们创建 OAuth 并将项目 ID 链接到他们的开发控制台然后访问我的应用程序我没有得到任何解决方案,如果有人知道请回复
【解决方案4】:

为了搭载 Jonathan Naguin 的出色答案,这里是获取刷新和访问令牌的 nodejs 版本:

//This script is to retreive a refresh token and an access token from Google API. 
//NOTE: The refresh token will only appear the first time your client credentials are used. 
//      I had to delete my client id within api console and create a new one to get the refresh token again.

//This is the downloaded json object from Google API Console. Just copy and paste over the template below.
var googleJson = {"web":{"auth_uri":"","client_secret":"","token_uri":"","client_email":"","redirect_uris":[""],"client_x509_cert_url":"","client_id":"","auth_provider_x509_cert_url":"","javascript_origins":[""]}};

//Retrieved from OAuth
var code            = ''; // Retrieved from the response of the URL generated by printGoogleAuthUrl(). You will need to be logged in as your publisher. Copy and paste the generated url. Copy the code parameter into this variable.
var refreshToken    = ''; // Retrieved from the printRefreshToken() function call. Requires the code variable to be filled out.
var accessToken     = ''; // Retrieved from the printAccessToken() function call. Requires the refreshToken variable to be filled out.


var querystring = require('querystring');
var https = require('https');
var fs = require('fs');

function printGoogleAuthUrl()
{
    console.log("https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=" + googleJson.web.redirect_uris[0] + "&client_id=" + googleJson.web.client_id);
}

function printRefreshToken()
{
    var post_data = querystring.stringify({
        'grant_type'    : 'authorization_code',
        'client_id'     : googleJson.web.client_id,
        'client_secret' : googleJson.web.client_secret,
        'code'          : code,
        'redirect_uri'  : googleJson.web.redirect_uris[0]
    });

    var post_options = {
      host: 'accounts.google.com',
      port: '443',
      path: '/o/oauth2/token',
      method: 'POST',
      headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': post_data.length
        }
    };

    var post_req = https.request(post_options, function(res) {
        res.setEncoding('utf8');
        var data = "";
        res.on('data', function (chunk) {
            data += chunk;
        });

        res.on('end', function(){
            var obj = JSON.parse(data);
            if(obj.refresh_token)
            {
                refreshToken = obj.refresh_token;
            }
            else
            {
                console.log("No refresh token found. I had to clear the web client id in Google Api Console and create a new one. There might be a better way here.");
            }   

            console.log(data);

        });
    });

    post_req.write(post_data);
    post_req.end();
}

function printAccessToken()
{
    var post_data = querystring.stringify({
        'grant_type'    : 'refresh_token',
        'client_id'     : googleJson.web.client_id,
        'client_secret' : googleJson.web.client_secret,
        'refresh_token' : refreshToken
    });

    var post_options = {
      host: 'accounts.google.com',
      port: '443',
      path: '/o/oauth2/token',
      method: 'POST',
      headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': post_data.length
        }
    };

    var post_req = https.request(post_options, function(res) {
        res.setEncoding('utf8');
        var data = "";
        res.on('data', function (chunk) {
            data += chunk;
        });

        res.on('end', function(){
            var obj = JSON.parse(data);
            if(obj.access_token)
                accessToken = obj.access_token;
            else
                console.log("No access token found.");

            console.log(data);

        });
    });

    post_req.write(post_data);
    post_req.end();
}

printGoogleAuthUrl();
//printRefreshToken();  
//printAccessToken();

【讨论】:

  • 我有一些疑问。我坚持了一个星期。我正在做一个应用程序来获取来自游戏商店的所有评论。它适用于在 Play 商店中拥有帐户的所有最终用户。 developers.google.com/android-publisher/getting_started 该文档指定我需要创建 oAuth,并且我需要在我的开发人员控制台中链接项目 ID 以访问我尝试过的审核 API,并且它工作正常。但是对于所有最终用户来说,他们创建 OAuth 并将项目 id 链接到他们的开发控制台然后访问我的应用程序我没有得到任何解决方案,如果有人知道请回复
【解决方案5】:

对于那些寻找 AndroidPublisher v3 的最新答案的人,请查看此处:https://stackoverflow.com/a/57943483/1028256

无需处理refreshToken & accessToken,只需几行代码。

对于 Android 客户端,我找到了这个“官方”示例代码:https://github.com/googlesamples/android-play-publisher-api/blob/master/v3/java/src/com/google/play/developerapi/samples/AndroidPublisherHelper.java,并且可以选择使用 .p12 文件或应用凭据来获取 AndroidPublisher。

【讨论】:

    【解决方案6】:

    我很确定您必须使用您的客户 ID,而不是电子邮件地址。它看起来像这样:37382847321922.apps.googleusercontent.com

    https://developers.google.com/android-publisher/authorization

    client_id=<the client ID token created in the APIs Console>
    

    而且我很确定您不需要 P12 文件。你只需要

    client_secret=<the client secret corresponding to the client ID>
    

    尝试首先从命令行手动执行此操作,使用“wget”。

    【讨论】:

      猜你喜欢
      • 2020-01-07
      • 2012-11-28
      • 2022-06-17
      • 2020-02-20
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 2014-03-08
      • 2013-03-09
      相关资源
      最近更新 更多