2012-04-20 46 views
5

Tôi đang cố truy cập API danh sách tài liệu của Google 3.0 với OAuth 2.0 nhưng tôi gặp một số sự cố với lỗi 401.OAuth - Mã thông báo không hợp lệ: Mã thông báo yêu cầu được sử dụng khi không được phép

Sau khi người dùng đã chấp nhận, mã của tôi là như sau:

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

Sau đó, trong dòng cuối cùng -getFeed() - ném ngoại lệ:

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> 

gì đang xảy ra? Trên một lớp thử nghiệm chính tĩnh hoạt động như một nét duyên dáng, nhưng khi tôi chạy nó trên máy chủ dòng này không hoạt động nữa. Bất kỳ ý tưởng?


SOLVED

Các thẻ truy cập cần phải được lấy ra theo cách này, với một GoogleOAuthHelper, không phải với GoogleOAuthParameters trực tiếp:

String accessToken = oauthHelper.getAccessToken(oauthParameters); 
+0

Ông có thể đưa giải pháp của bạn trong một câu trả lời và chấp nhận câu trả lời đó? Bằng cách này, câu hỏi được đánh dấu là đã được giải quyết và nếu có ai trên bài đăng này (vì bất kỳ lý do nào), câu trả lời sẽ dễ dàng được tìm thấy. –

+0

oauthHelper này là gì? –

Trả lời

13

Bạn đang không sử dụng OAuth 2.0 nhưng OAuth 1.0 với HMAC-SHA1 làm phương thức chữ ký. Để sử dụng OAuth 2.0, bạn cần ít nhất phiên bản 1.47.0 của thư viện gdata-java-client và phiên bản 1.8.0 beta của thư viện google-oauth-java-client.

Sử dụng thư viện google-api-java-client cung cấp các lớp trợ giúp để giải quyết việc triển khai OAuth 2.0 của Google.

Để lấy chứng chỉ OAuth 2.0, bạn có thể sử dụng đoạn mã này:

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

    // … 
} 

Khi bạn có chứng chỉ OAuth 2.0, bạn có thể ủy quyền cho một đối tượng dịch vụ như sau:

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

    // ... 
} 

Các CLIENT_ID , CLIENT_SECRET có thể được truy lục từ APIs ConsoleREDIRECT_URI phải khớp với một đã được đăng ký với Dự án API của bạn.

+0

Cảm ơn. Bạn đa đung. Đã sửa lỗi để chạy với OAuth2. Nhưng mã của bạn có lỗi, câu này là ngược: .setRefreshToken (response.getAccessToken()). SetAccessToken (response.getRefreshToken()); – xuso

+0

Cảm ơn, tôi đã sửa mẫu :-) – Alain

+0

bạn có thể cung cấp liên kết cho phụ thuộc maven cho jar này-google-api-java-client không? – Sanket

3

Dưới đây là làm thế nào để thêm OAuth2.0 dấu hiệu cho Dịch vụ GData:

SpreadsheetService service = new SpreadsheetService("MySpreadsheetIntegration-v1"); 

service.setOAuth2Credentials(new Credential(BearerToken 
    .authorizationHeaderAccessMethod()) 
    .setFromTokenResponse(new TokenResponse().setAccessToken(mToken))); 

Hãy chắc chắn để nhập khẩu tất cả các thư viện cần thiết (đó là rất nhiều).

Mở thẻ Android sẽ thu được sử dụng dịch vụ Google Play OAuth cơ chế:

String token = GoogleAuthUtil.getToken(String email, String scopes); 
+0

Câu trả lời này bổ sung hoàn toàn cho bình chọn nhiều nhất ... @ zavidovych bạn có cân nhắc chỉnh sửa câu trả lời khác để làm phong phú nó không? –

Các vấn đề liên quan