2012-04-20 15 views
5

Sto cercando di accedere a Google Documenti Lista API 3.0 con OAuth 2.0 ma sto avendo alcuni problemi con un errore 401.OAuth - non valido token: Richiesta segno usato quando non ammessi

Dopo utenti hanno accettato, il mio codice è il seguente:

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

Poi, nell'ultima riga -getFeed() - genera l'eccezione:

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> 

Cosa sta succedendo? Su una classe di test principale statica funziona come un incantesimo, ma quando lo eseguo sul server questa linea non funziona più. Qualche idea?


risolto

Il token di accesso ha bisogno di essere recuperati in questo modo, con un GoogleOAuthHelper, non con gli GoogleOAuthParameters direttamente:

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

Potrebbe mettere la soluzione in una risposta e accettare che la risposta? In questo modo la domanda è contrassegnata come risolta e se qualcuno ottiene su questo post (per qualsiasi motivo) la risposta sarà facile da trovare. –

+0

Cos'è questo oauthHelper? –

risposta

13

Non si sta utilizzando OAuth 2.0, ma OAuth 1.0 con HMAC-SHA1 come metodo di firma. Per utilizzare OAuth 2.0, è necessaria almeno la versione 1.47.0 della libreria gdata-java-client e la versione 1.8.0-beta della libreria google-oauth-java-client.

Utilizzando la libreria google-api-java-client fornisce classi helper per affrontare 2.0 implementazione OAuth di Google.

Per recuperare credenziali OAuth 2.0, è possibile utilizzare questo frammento di codice:

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

    // … 
} 

Una volta che hai le credenziali OAuth 2.0, è possibile autorizzare un oggetto servizio come segue:

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

    // ... 
} 

Il CLIENT_ID , CLIENT_SECRET può essere recuperato dallo APIs Console e lo REDIRECT_URI deve corrispondere a uno che è stato registrato con il progetto API.

+0

Grazie. Avevi ragione. Risolto già per funzionare con OAuth2. Ma il tuo codice ha un errore, questa frase è inversa: .setRefreshToken (response.getAccessToken()). SetAccessToken (response.getRefreshToken()); – xuso

+0

Grazie, ho corretto il campione :-) – Alain

+0

puoi fornire il link per la dipendenza da maven per questo jar google-api-java-client? – Sanket

3

Ecco come aggiungere OAuth2.0 token per GData Servizio:

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

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

Assicurarsi di importare tutte le librerie necessarie (che è molto).

Il gettone di Android dovrebbe essere ottenuto utilizzando Google Play Services OAuth meccanismo:

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

Questa risposta completa perfettamente quella più votata ... @ zavidovych hai considerato di modificare l'altra risposta per arricchirla? –

Problemi correlati