web-dev-qa-db-ja.com

サーバーからのOAuth2「無効な付与」応答

クライアントに、GoogleAPIプロジェクトを作成した承認済みのGmailアカウントでこのURLをヒットするように依頼します。

https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=http://www.XXXXXXXX.com/oauth2callback&client_id=XXXXXX.apps.googleusercontent.com&state=profile&approval_Prompt=force

次に、リダイレクトされたURLからコードパラメータを提供するように彼に依頼します

http://www.XXXXXXXX.com/oauth2callback?code=4/jUxc2MdX0xmF-b4_I6v2SLMQMuxO.cvQLVEpcJMUXOl05ti8ZT3ZvsT9ddwI

それから私自身、このフォームに次の情報を投稿します。

<form action="https://accounts.google.com/o/oauth2/token" method="post" >

<input type="hidden" name="grant_type" value="authorization_code" >
<input type="text" name="code" value="**is the one i recieved from previous step**">
<input type="hidden" name="client_id" value="XXXXXXX.apps.googleusercontent.com" >
<input type="hidden" name="client_secret" value="XXXXXXXXXXXX" >
<input type="hidden" name="redirect_uri" value="http://www.XXXXXX.com/oauth2callback" >
<input type="submit" value="Submit">

</form>

その後、次のエラーが発生します

{
    "error" : "invalid_grant"
}

コードurlparamを自分で生成し、次の手順を実行するとき。次の応答が正常に表示されます

{
  "access_token" : "XXXXXXStBkRnGyZ2mUYOLgls7QVBxOg82XhBCFo8UIT5gM",
  "token_type" : "Bearer",
  "expires_in" : 3600,
  "refresh_token" : "XXXXXX3SEBX7F2cfrHcqJEa3KoAHYeXES6nmho"
}

しかし、クライアントがurl param "code"を生成すると、無効な付与エラーが表示されます。

私のクライアントは英国にいて、私は別の国にいます。クライアントが別の国でコードパラメータを生成していて、そのコードを別の国で使用しているため、エラーかどうかを誰かに確認できますか?

前もって感謝します。

12
shaikh

クライアントに、コードとそれに続く更新トークンを自分で生成するように依頼することができます。 refresh_tokenが生成される上記のフォームへのアクセスを彼に与えます。

次に、refresh_tokenを使用してaccess_tokensを生成できます。

それがあなたの問題を解決することを願っています。

4
shaikh

同じコードで正しいアクセストークンが取得されることがあるという事実ではなく、invalid_grantエラーに悩まされました。

シェイクの答えは私を正しい方向に導いてくれました。

まず、アクセスコードを次の場所から取得しようとします。

https://accounts.google.com/o/oauth2/auth

ユーザーは「許可を許可する」画面に移動し、アプリはアクセスコードを受け取ります。

そのアクセスコードを使用して、アクセストークンを取得しようとします。

https://accounts.google.com/o/oauth2/token

最初の試行では、grant_type = authentication_codeでaccess_tokenが返されますが、access_tokenが提供されると、grant_type = authenticationを再度受け取ることは期待できなくなり、代わりに、grant_type = refresh_tokenを受け取るようになります。

仲間の場合Android開発者のコ​​ードは次のとおりです。

String accessToken = null, refreshToken = null;
HttpPost httppost = new HttpPost(https://accounts.google.com/o/oauth2/token);
HttpParams myParams = new BasicHttpParams();
httppost.setHeader("Content-type", "application/x-www-form-urlencoded");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
nameValuePairs.add(new BasicNameValuePair("client_id", BLOGGER_CLIENT_ID));
SharedPreferences prefs = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
String bloggerAccessToken = prefs.getString(PREFERENCES_KEY_BLOGGER_ACCESS_TOKEN, null);

if(bloggerAccessToken != null && bloggerAccessToken.length() > 0){
    nameValuePairs.add(new BasicNameValuePair("refresh_token",  prefs.getString(PREFERENCES_KEY_BLOGGER_REFRESH_TOKEN, null)));
    nameValuePairs.add(new BasicNameValuePair("grant_type",    "refresh_token"));
} else{
    nameValuePairs.add(new BasicNameValuePair("code",  prefs.getString(PREFERENCES_KEY_BLOGGER_ACCESS_CODE, null)));
    nameValuePairs.add(new BasicNameValuePair("grant_type",    "authorization_code"));
    nameValuePairs.add(new BasicNameValuePair("redirect_uri",  "http://localhost"));
}

httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpClient httpClient = new DefaultHttpClient(myParams);
response = httpClient.execute(httppost);

String returnedJsonStr = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = new JSONObject(returnedJsonStr);
accessToken = jsonObject.getString("access_token");
if(jsonObject.has("refresh_token"))
    refreshToken = jsonObject.getString("refresh_token");
6
Sourab Sharma