0

私は Android アプリのバックエンド Web サービス開発者です。サブスクリプションとしてアプリにサービスを提供しており、サブスクリプションの購入に Google Play を使用することを検討しています。アプリでユーザーが利用できるサービスを追跡するバックエンド ライセンス サーバーがあります。

特定の理由により、バックエンドから購入のサブスクリプション ステータスを取得したいと考えています。しかし、Google の OAuth2 Web サービスからアクセス トークンとリフレッシュ トークンを取得する際に問題が発生しました。

次のページの指示に従いました: Google Play Android Developer API

クライアント ID のセットアップに使用される Google アカウントに直接アクセスすることはできません。また、最初のコードを取得するための Web 呼び出しを実行する手順を実行するためのアクセス権を持つマネージャーがいて、それが私に与えられました。次に、それを使用してHTTP POSTで許可認証を呼び出しますが、「invalid_grant」エラーのみを含むJsonでHTTP 400を取得します。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 とシークレットに対して最初の authorization_code 呼び出しを行った場合。呼び出しを再試行しても、結果の JSON で refresh_token が返されません。現在の access_token のみ。だから、どこかに保管してください!

于 2013-01-14T21:25:30.560 に答える