OAuth - 无效令牌:请求令牌在不允许时使用 [英] OAuth - Invalid token: Request token used when not allowed
问题描述
我正在尝试使用 OAuth 2.0 访问 Google 的文档列表 API 3.0,但遇到了 401 错误.
I'm trying to access Google's Documents List API 3.0 with OAuth 2.0 but I'm having some troubles with a 401 Error.
用户接受后,我的代码如下:
After user have accepted, my code is the following:
GoogleOAuthParameters oauthParameters = new GoogleOAuthParameters();
oauthParameters.setOAuthConsumerKey(CLIENT_ID);
oauthParameters.setOAuthConsumerSecret(CLIENT_SECRET);
oauthParameters.setOAuthToken(token);
oauthParameters.setOAuthTokenSecret(tokenSecret);
oauthParameters.setScope("https://docs.google.com/feeds/");
service = new DocsService("myapp");
service.setOAuthCredentials(oauthParameters, new OAuthHmacSha1Signer());
DocumentListFeed feed = service.getFeed(new URL("https://docs.google.com/feeds/default/private/full/?v=3"), DocumentListFeed.class);
然后,在最后一行 -getFeed()- 抛出异常:
Then, in the last line -getFeed()- throws the exception:
com.google.gdata.util.AuthenticationException: Token invalid - Invalid token: Request token used when not allowed.
<HTML>
<HEAD>
<TITLE>Token invalid - Invalid token: Request token used when not allowed.</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Token invalid - Invalid token: Request token used when not allowed.</H1>
<H2>Error 401</H2>
</BODY>
</HTML>
这是怎么回事?在静态主测试类上工作就像一个魅力,但是当我在服务器上运行它时,这条线不再起作用.有什么想法吗?
What's going on? On a static main test class works like a charm, but when I run it on the server this line does not works anymore. Any idea?
已解决
需要以这种方式检索访问令牌,使用 GoogleOAuthHelper,而不是直接使用 GoogleOAuthParameters:
The access token needs to be retrieved this way, with a GoogleOAuthHelper, not with the GoogleOAuthParameters directly:
String accessToken = oauthHelper.getAccessToken(oauthParameters);
推荐答案
您使用的不是 OAuth 2.0,而是使用 HMAC-SHA1 作为签名方法的 OAuth 1.0.要使用 OAuth 2.0,您至少需要 gdata-java-client 的 1.47.0 版 库和 google-oauth- 的 1.8.0-beta 版java-client 库.
You are not using OAuth 2.0 but OAuth 1.0 with HMAC-SHA1 as the signature method. To use OAuth 2.0, you need at least version 1.47.0 of the gdata-java-client library and version 1.8.0-beta of the google-oauth-java-client library.
使用 google-api-java-client 库提供帮助类来处理 Google 的 OAuth 2.0 实现.
Using the google-api-java-client library provides helper classes to deal with Google's OAuth 2.0 implementation.
要检索 OAuth 2.0 凭据,您可以使用以下代码片段:
To retrieve OAuth 2.0 credentials, you can use this code snippet:
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;
public class MyClass {
// Retrieve the CLIENT_ID and CLIENT_SECRET from an APIs Console project:
// https://code.google.com/apis/console
static String CLIENT_ID = "<YOUR_CLIENT_ID>";
static String CLIENT_SECRET = "<YOUR_CLIENT_SECRET>";
// Change the REDIRECT_URI value to your registered redirect URI for web
// applications.
static String REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
// Add other requested scopes.
static List<String> SCOPES = Arrays.asList("https://docs.google.com/feeds");
/**
* Retrieve OAuth 2.0 credentials.
*
* @return OAuth 2.0 Credential instance.
*/
static Credential getCredentials() throws IOException {
HttpTransport transport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
// Step 1: Authorize -->
String authorizationUrl =
new GoogleAuthorizationCodeRequestUrl(CLIENT_ID, REDIRECT_URI, SCOPES).build();
// Point or redirect your user to the authorizationUrl.
System.out.println("Go to the following link in your browser:");
System.out.println(authorizationUrl);
// Read the authorization code from the standard input stream.
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("What is the authorization code?");
String code = in.readLine();
// End of Step 1 <--
// Step 2: Exchange -->
GoogleTokenResponse response =
new GoogleAuthorizationCodeTokenRequest(transport, jsonFactory, CLIENT_ID, CLIENT_SECRET,
code, REDIRECT_URI).execute();
// End of Step 2 <--
// Build a new GoogleCredential instance and return it.
return new GoogleCredential.Builder().setClientSecrets(CLIENT_ID, CLIENT_SECRET)
.setJsonFactory(jsonFactory).setTransport(transport).build()
.setAccessToken(response.getAccessToken()).setRefreshToken(response.getRefreshToken());
}
// …
}
拥有 OAuth 2.0 凭据后,您可以按如下方式授权服务对象:
Once you have the OAuth 2.0 credential, you can authorize a service object as follow:
// ...
import com.google.api.client.auth.oauth2.Credential;
import com.google.gdata.client.docs.DocsService;
import com.google.gdata.data.docs.DocumentListEntry;
import com.google.gdata.data.docs.DocumentListFeed;
import com.google.gdata.util.ServiceException;
// ...
import java.io.IOException;
import java.net.URL;
// ...
public class MyClass {
// …
/**
* Print document entries using the provided authorized DocsService.
*
* @param credential OAuth 2.0 credential to use to authorize the requests.
* @throws IOException
* @throws ServiceException
*/
static void printDocuments(Credential credential) throws IOException, ServiceException {
// Instantiate and authorize a new DocsService object.
DocsService service = new DocsService("<YOUR_APPLICATION_NAME>");
service.setOAuth2Credentials(credential);
// Send a request to the Documents List API to retrieve document entries.
URL feedUri = new URL("https://docs.google.com/feeds/default/private/full/");
DocumentListFeed feed = service.getFeed(feedUri, DocumentListFeed.class);
for (DocumentListEntry entry : feed.getEntries()) {
System.out.println("Title: " + entry.getTitle().getPlainText());
}
}
// ...
}
CLIENT_ID
、CLIENT_SECRET
可以从 API 控制台 和 REDIRECT_URI
必须与已在您的 API 项目中注册的一致.
The CLIENT_ID
, CLIENT_SECRET
can be retrieved from the APIs Console and the REDIRECT_URI
must match one that has been registered with your API Project.
这篇关于OAuth - 无效令牌:请求令牌在不允许时使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!