OAuth - 无效令牌:不允许时使用请求令牌 [英] OAuth - Invalid token: Request token used when not allowed

查看:1057
本文介绍了OAuth - 无效令牌:不允许时使用请求令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用OAuth 2.0访问Google的Documents List API 3.0,但我遇到了401错误的麻烦。



用户接受后,我的代码如下:

  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(新网址(https://docs.google.com/feeds/default/private/full/?v=3),DocumentListFeed.class);

然后,在最后一行-getFeed()中抛出异常:

  com.google.gdata.util.AuthenticationException:令牌无效 - 令牌无效:不允许时使用请求令牌。 
< HTML>
< HEAD>
< TITLE>令牌无效 - 令牌无效:不允许时使用请求令牌。< / TITLE>
< / HEAD>
< BODY BGCOLOR =#FFFFFFTEXT =#000000>
< H1>令牌无效 - 令牌无效:不允许时使用请求令牌。< / H1>
< H2>错误401< / H2>
< / BODY>
< / HTML>

发生了什么事?在静态主测试类上工作就像一个魅力,但当我在服务器上运行它时,这条线不再起作用了。有什么想法?






已解决



访问令牌需要以这种方式检索,使用GoogleOAuthHelper,而不是直接使用GoogleOAuthParameters:

  String accessToken = oauthHelper .getAccessToken(oauthParameters); 


解决方案

您没有使用OAuth 2.0,而是使用带有HMAC的OAuth 1.0 -SHA1作为签名方法。要使用OAuth 2.0,您至少需要 gdata-java-client的版本1.47.0 google-oauth-的库和1.8.0-beta版本使用 google-api-java-client 库提供了帮助类来处理Google的OAuth 2.0实现。



要检索OAuth 2.0凭据,您可以使用以下代码段:

  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;

公共类MyClass {

//从API控制台项目中检索CLIENT_ID和CLIENT_SECRET:
// https://code.google.com/apis / console
static String CLIENT_ID =< YOUR_CLIENT_ID>;
static String CLIENT_SECRET =< YOUR_CLIENT_SECRET>;
//将REDIRECT_URI值更改为web
//应用程序的已注册重定向URI。
static String REDIRECT_URI =urn:ietf:wg:oauth:2.0:oob;
//添加其他请求的范围。
静态列表< String> SCOPES = Arrays.asList(https://docs.google.com/feeds);

/ **
*检索OAuth 2.0凭据。
*
* @return OAuth 2.0 Credential实例。
* /
static Credential getCredentials()抛出IOException {
HttpTransport transport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();

//第1步:授权 - >
String authorizationUrl =
new GoogleAuthorizationCodeRequestUrl(CLIENT_ID,REDIRECT_URI,SCOPES).build();

//将用户指向或重定向到authorizationUrl。
System.out.println(转到浏览器中的以下链接:);
System.out.println(authorizationUrl);

//从标准输入流中读取授权码。
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println(什么是授权码?);
String code = in.readLine();
//步骤1结束< -

//步骤2:交流 - >
GoogleTokenResponse response =
new GoogleAuthorizationCodeTokenRequest(transport,jsonFactory,CLIENT_ID,CLIENT_SECRET,
code,REDIRECT_URI).execute();
//步骤2结束< -

//构建一个新的GoogleCredential实例并将其返回。
返回新的GoogleCredential.Builder()。setClientSecrets(CLIENT_ID,CLIENT_SECRET)
.setJsonFactory(jsonFactory).setTransport(transport).build()
.setAccessToken(response.getAccessToken())。 setRefreshToken(response.getRefreshToken());
}

// ...
}

获得OAuth 2.0凭据后,您可以按如下方式授权服务对象:

  // ... 
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;
// ...

公共类MyClass {
// ... ...

/ **
*使用提供的打印文件条目授权DocsService。
*
* @param凭证用于授权请求的OAuth 2.0凭据。
* @throws IOException
* @throws ServiceException
* /
static void printDocuments(Credential credential)throws IOException,ServiceException {
//实例化并授权新的DocsService宾语。
DocsService服务=新文档服务(< YOUR_APPLICATION_NAME>);
service.setOAuth2Credentials(credential);

//向Documents List API发送请求以检索文档条目。
网址feedUri =新网址(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 /code.google.com/apis/console\"rel =noreferrer> API控制台 REDIRECT_URI 必须与已在API项目中注册的一个匹配。


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);

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?


SOLVED

The access token needs to be retrieved this way, with a GoogleOAuthHelper, not with the GoogleOAuthParameters directly:

String accessToken = oauthHelper.getAccessToken(oauthParameters);

解决方案

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.

Using the google-api-java-client library provides helper classes to deal with Google's OAuth 2.0 implementation.

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());
  }

  // …
}

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());
    }
  }

  // ...
}

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆