谷歌的OAuth2 - 访问令牌和放大器;刷新令牌 - > invalid_grant / code已经被赎回 [英] Google OAuth2 - access token & refresh token -> invalid_grant/Code was already redeemed
问题描述
我的目标是有某种长寿命的访问令牌,使我的Android应用程序可以读取用户的谷歌日历当天的事件,而不需要每次都需要用户的批准。
My goal is to have some kind of long lived access token so that my Android app can read the events of a user's Google Calendar for the day without requiring user approval every time.
我能够生成 - 我认为是 - 一次性授权code;但是,当我把这个给我的服务器端,应用程序引擎,我得到以下错误响应:
I am able to generate -- what I think is -- a one-time authorization code; however, when I send this to my server side, app engine, I get the following error response:
400 OK
{
错误:invalid_grant
ERROR_DESCRIPTION:code已经被赎回。
}
这是正在引发的异常。我只是抓住它,并把它发回给自己作为调试的一种方式。
That is the exception that is being thrown. I'm just catching it and sending it back to myself as a way of debugging.
一次性code我得到打头的 4 /膀胱输尿管返流的,所以我认为这是一个一次性的code和不经常访问令牌。
The one-time code I get starts with 4/VUr so I assume it is a one-time code and not a regular access token.
目前,在Android上,我允许用户使用Google+登入,让我有自己的电子邮件地址。从那里,我要求的一次性授权code 有以下code:
Currently, on Android, I allow a user to sign in using Google+ so that I have their email address. From there I request a one-time authorization code with the following code:
try {
Bundle appActivities = new Bundle();
appActivities.putString(GoogleAuthUtil.KEY_REQUEST_VISIBLE_ACTIVITIES, "http://schemas.google.com/AddActivity");
String scopes = "oauth2:server:client_id:" + Constants.SERVER_CLIENT_ID + ":api_scope:https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/calendar";
//Plus.SCOPE_PLUS_LOGIN + " " + CalendarScopes.CALENDAR_READONLY;
String acctName = "myGmail";
String token = GoogleAuthUtil.getToken(getApplicationContext(), acctName, scopes, appActivities);
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), 257/*REQUEST_AUTHORIZATION/*/);
} catch (Exception e) {
e.printStackTrace();
}
这code是<一个href=\"https://developers.google.com/+/mobile/android/sign-in#enable_server-side_api_access_for_your_app\"相对=nofollow称号=这里>这里,似乎这是我必须做的。
This code is from here and it seems that this is what I must do.
我再发这个code到我的App Engine的端点。我用code从<一个href=\"https://developers.google.com/+/web/signin/server-side-flow#step_8_initialize_the_google_api_client_library_and_start_the_google_service\"相对=nofollow称号=这里>这里请求访问和刷新令牌。
I then send this code to my App Engine Endpoint. I use code from here to request a access and refresh token.
以下是code,我作为一个简单的测试是:
The following is the code that I use as a simple test:
HttpTransport transport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
//ArrayList<String> scopes = new ArrayList<>();
//scopes.add("https://www.googleapis.com/auth/plus.login");
//scopes.add("https://www.googleapis.com/auth/calendar");
GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory,
SERVER_CLIENT_ID, SERVER_CLIENT_SECRET, code, "postmessage")/*.setScopes(scopes)*/.execute();
//urn:ietf:wg:oauth:2.0:oob
//postmessage
code = tokenResponse.getRefreshToken();
当我将它实例未能正确 GoogleAuthorization codeTokenRequest
It is failing right when I instantiate GoogleAuthorizationCodeTokenRequest
要仅举几例我所看到的
https://developers.google.com/accounts/docs/CrossClientAuth#offlineAccess
<一href=\"http://stackoverflow.com/questions/14309726/google-api-php-refresh-token-returns-invalid-grant\">Google-api-php刷新令牌返回invalid_grant
<一href=\"http://stackoverflow.com/questions/18361054/getting-google-oauth-authorization-token-from-android-return-with-invalid-scope\">getting从谷歌Android-授权的OAuth令牌invalid_scope /未知错误返回
To name a few I have seen
https://developers.google.com/accounts/docs/CrossClientAuth#offlineAccess
Google-api-php Refresh Token returns invalid_grant
getting Google oauth authorization token from Android- return with invalid_scope/ Unknown error
设置重定向URI不同没有工作。
我没有填写同意画面为我的应用程序引擎项目。都安装Android客户端ID和Web应用程序客户端ID在同一个项目中。我对Web应用程序设置为xxxxxxxx.appspot.com我的应用程序重定向URI。
Setting the redirect uri differently did not work. I did fill out the consent screen for my app engine project. Both installed Android client id and web application client id are in the same project. I have the redirect uri for the web application set to xxxxxxxx.appspot.com for my app.
摇篮我主要的应用程序:
Gradle for my main app:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
// compile 'com.google.api-client:google-api-client:1.18.0-rc'
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'org.altbeacon:android-beacon-library:2.1.3'
compile 'com.google.apis:google-api-services-calendar:v3-rev118-1.19.1'
compile 'com.google.api-client:google-api-client-android:1.18.0-rc'
compile 'com.google.android.gms:play-services:6.5.87'
compile 'com.google.http-client:google-http-client-jackson:1.19.0'
compile project(path: ':beaconBackend', configuration: 'android-endpoints')
}
摇篮为我的后端:
Gradle for my backend:
dependencies {
appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.14'
compile 'com.google.appengine:appengine-endpoints:1.9.14'
compile 'com.google.appengine:appengine-endpoints-deps:1.9.14'
compile 'javax.servlet:servlet-api:2.5'
}
任何帮助真的会AP preciated!谢谢!
Any help would really be appreciated! Thanks!
另外请注意,我已经尝试无效/撤销当前访问令牌(或一次性code?)。
Also, note that I have tried invalidating/revoking the current access token (or one-time code?).
我只需要一种方法有某种长期居住访问令牌无后第一时间的用户交互。
I just need a way to have some kind of long living access token without user interaction after the first time.
推荐答案
这已经有一段时间,因为我曾在这个项目上 - 它不再需要
It's been a while since I worked on this project -- it was no longer needed.
问题是服务器端的应用程序中。我只是没有正确地要求它。
一旦我的服务器端应用程序(App Engine的端点)从Android应用程序收到刷新令牌我没有在服务器端以下。
The problem was within the server side app. I just wasn't requesting it correctly. Once my server side app (App Engine Endpoint) received the refresh token from the Android app I did the following on the server side.
private String refreshAccessToken(String refreshToken, String clientId, String clientSecret) throws IOException {
try {
TokenResponse response =
new GoogleRefreshTokenRequest(new NetHttpTransport(), new JacksonFactory(),
refreshToken, clientId, clientSecret).execute();
return response.getAccessToken();
} catch (TokenResponseException e) {
return null;
}
}
这篇关于谷歌的OAuth2 - 访问令牌和放大器;刷新令牌 - &GT; invalid_grant / code已经被赎回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!