0

我是 Android 应用程序的后端 Web 服务开发人员。我们正在以订阅形式为应用提供服务,并正在考虑使用 Google Play 进行订阅购买。我们有一个后端许可证服务器来跟踪应用程序中可供用户使用的服务。

出于某些原因,我们希望从后端获取购买的订阅状态。但是我遇到了从 Google 的 OAuth2 网络服务获取访问和刷新令牌的问题。

我已按照以下页面的说明进行操作:Google Play Android Developer API

我没有直接访问用于设置客户端 ID 的 Google 帐户的权限,并且我让经理有权执行网络呼叫以获取初始代码,然后将其提供给我。然后我使用它通过 HTTP POST 调用授权身份验证,但使用 Json 获取 HTTP 400,只包含“invalid_grant”错误。以下是 POST 代码的示例:

    string postData = String.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}&grant_type=authorization_code",
        oauthCode,
        clientId,
        clientSecret,
        redirectURL
        );
    byte[] data = Encoding.UTF8.GetBytes(postData);

    try
    {

        HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create("https://accounts.google.com/o/oauth2/token");
        wreq.Method = "POST";
        wreq.ContentType = "application/x-www-form-urlencoded";
        wreq.ContentLength = data.Length;
        wreq.Accept = "application/json";

        using (Stream wstream = wreq.GetRequestStream())
        {
            wstream.Write(data, 0, data.Length);
        }

        HttpWebResponse wresp = (HttpWebResponse)wreq.GetResponse();
        if (wresp.StatusCode == HttpStatusCode.OK)
        {
            using (Stream rstream = wresp.GetResponseStream())
            {
                StringBuilder jresp = new StringBuilder();
                byte[] buffer = new byte[512];
                int read = 0;

                while ((read = rstream.Read(buffer, 0, buffer.Length)) > 0)
                    jresp.Append(Encoding.UTF8.GetString(buffer, 0, read));

                Console.WriteLine(jresp.ToString());
            }
        }
        else
            Console.WriteLine("damn...");

    }
    catch (WebException wex)
    {
        Console.WriteLine(wex.ToString());
        Console.WriteLine("================================");


        if (wex.Response != null)
        {
            StringBuilder inner = new StringBuilder();
            byte[] buffer = new byte[512];
            int read = 0;

            using (Stream xstream = wex.Response.GetResponseStream())
            {
                while ((read = xstream.Read(buffer, 0, buffer.Length)) > 0)
                    inner.Append(Encoding.UTF8.GetString(buffer, 0, read));
            }

            Console.WriteLine(inner.ToString());
        }

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }

我担心我将无法从与初始代码身份验证 Web 浏览器调用不同的位置执行此操作,并且无法从 Web 浏览器体验的后端执行访问/刷新令牌。

4

1 回答 1

0

我写这个作为答案,以防其他人需要它。这是我得出的结论:

最初的“grant_type=authorization_code”调用似乎必须在与 OAuth 代码请求相同的会话中完成。

我能够访问 Google 帐户凭据,并让重定向代码执行初始访问令牌请求,该请求也返回刷新令牌。它能够做到这一点。这似乎意味着初始访问和刷新令牌请求无法在后端进程中完成,而必须在会话环境(例如 Web 浏览器)中完成。

然后我转身从 C# 发出一个标准的发布请求,用接收到的刷新令牌刷新访问令牌,并且能够获得一个新的访问令牌。

编辑:作为提醒。如果您已经为特定的客户端 ID 和密码完成了初始授权代码调用。任何重试调用它,都不会在结果 JSON 中返回 refresh_token。只有当前的 access_token。因此,请确保将其存放在某个地方!

于 2013-01-14T21:25:30.560 回答