2013-03-05 35 views
8

sto usando il codice followin per ottenere un token di accesso, dopo il collegamento a Google+, per ottenere il profilo informazioni e e-mail:Google Plus per Android: credenziali non valide

String sAccessToken = GoogleAuthUtil.getToken(this,mPlusClient.getAccountName() + "", 
          "oauth2:" + Scopes.PLUS_PROFILE + " 
          https://www.googleapis.com/auth/userinfo.profile 
          https://www.googleapis.com/auth/userinfo.email"); 

Questo token di accesso non sto immagazzinando e cercando di riutilizzare. Invece chiedo sempre un token di accesso, aspettandomi un nuovo (diverso) token, in modo da non dover controllare se è scaduto ecc.

Ma sto ricevendo lo stesso token di accesso ogni volta che chiedo. Ho disinstallato l'app, cancellato i dati di App Google+ e ancora ottengo lo stesso token di accesso.

il problema reale è, usando questo token di accesso dà l'errore 401 - "message": "Invalid Credentials"

{ 
"error": { 
    "errors": [ 
    { 
    "domain": "global", 
    "reason": "authError", 
    "message": "Invalid Credentials", 
    "locationType": "header", 
    "location": "Authorization" 
    } 
    ], 
    "code": 401, 
    "message": "Invalid Credentials" 
} 
} 

Questa è una risposta sul browser.

Su un dispositivo ottengo questo in Logcat:

02-25 02:09:46.919: W/System.err(3022): java.io.FileNotFoundException: https://www.googleapis.com/oauth2/v1/userinfo 
02-25 02:09:46.929: W/System.err(3022):  at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:521) 
02-25 02:09:46.929: W/System.err(3022):  at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:258) 
02-25 02:09:46.929: W/System.err(3022):  at com.example.gmaillogin.MainActivity$connectAsyncTask.doInBackground(MainActivity.java:269) 
02-25 02:09:46.929: W/System.err(3022):  at com.example.gmaillogin.MainActivity$connectAsyncTask.doInBackground(MainActivity.java:1) 
02-25 02:09:46.929: W/System.err(3022):  at android.os.AsyncTask$2.call(AsyncTask.java:185) 
02-25 02:09:46.929: W/System.err(3022):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
02-25 02:09:46.929: W/System.err(3022):  at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
02-25 02:09:46.929: W/System.err(3022):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
02-25 02:09:46.929: W/System.err(3022):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
02-25 02:09:46.929: W/System.err(3022):  at java.lang.Thread.run(Thread.java:1019) 

Linea 269:

urlConnection = (HttpURLConnection) url.openConnection(); 

codice completo:

URL url = new URL("https://www.googleapis.com/oauth2/v1/userinfo"); 
String sAccessToken = GoogleAuthUtil.getToken(
         MainActivity.this, 
         mPlusClient.getAccountName() + "", 
         "oauth2:" + Scopes.PLUS_PROFILE + " 
              https://www.googleapis.com/auth/userinfo.profile 
              https://www.googleapis.com/auth/userinfo.email"); 

      Log.d("sAccessToken = ", "" + sAccessToken); 
      urlConnection = (HttpURLConnection) url.openConnection(); 
      urlConnection.setRequestProperty("Authorization", "Bearer " 
        + sAccessToken); 

      BufferedReader r = new BufferedReader(new InputStreamReader(
        urlConnection.getInputStream(), "UTF-8")); 
      StringBuilder total = new StringBuilder(); 
      String line; 
      while ((line = r.readLine()) != null) { 
       total.append(line); 
      } 
      line = total.toString(); 

EDIT:

Questo è sicuramente perché il token di accesso è scaduto. Il che era previsto, ma ho pensato di ottenere un nuovo token di accesso ogni volta che chiamo.

Ma, come detto here:

Se il dispositivo Android ha già un token di autenticazione (per il particolare servizio GData si sta cercando di accesso), sarà restituito a voi

Quindi, devo fare questo:

if (server indicates token is invalid) { 
       // invalidate the token that we found is bad so that GoogleAuthUtil won't 
       // return it next time (it may have cached it) 
       GoogleAuthUtil.invalidateToken(Context, String)(context, token); 
       // consider retrying getAndUseTokenBlocking() once more 
       return; 
      } 

come il docs dicono

Ma come posso verificare se il token di accesso è scaduto o non valido?

Rilevando l'eccezione: è l'unica soluzione?

In realtà l'eccezione è java.io.FileNotFoundException che non ha senso.

+0

C'è un motivo per cui si sta tentando di farlo manualmente piuttosto che utilizzare i metodi forniti su PlusClient? Il cliente deve gestire automaticamente gli scambi di token per conto della tua app. – BrettJ

+0

Ho seguito [questo] (https://developers.google.com/+/mobile/android/people#retrieve_an_authenticated_users_email_address) per ottenere il token di accesso. Qual è l'altro modo in cui viene gestito automaticamente? –

risposta

4

Copertura delle basi qui: Avete register a Google APIs Console project e create un ID client OAuth 2.0 per la vostra app per Android, specificando il nome del pacchetto dell'app e l'impronta digitale SHA-1 del vostro certificato (test o pungolo)?

Spesso il messaggio 401 di credenziali non valide è dovuto al fatto che il progetto della console API non è stato configurato o una delle impostazioni non è valida.

I passi a piedi attraverso quel processo istituito appositamente per l'Google+ SDK sono qui: https://developers.google.com/+/mobile/android/getting-started

Modifica

Il PlusClient in grado di gestire automaticamente i gettoni per voi. Suggerirei di utilizzare i metodi che lo PlusClient fornisce e che consentono al client di gestire i token anziché eseguirlo manualmente. Se avete bisogno di dati e-mail o tramite il profilo PlusClient vedono PlusClient.loadPerson() e per la posta elettronica PlusClient.getAccountName(), maggiori dettagli a https://developers.google.com/+/mobile/android/people

+1

Sì, ho fatto quello che hai menzionato nella risposta. Dopo alcune ricerche ho scoperto che è sicuramente dovuto al 'Access Token'. ** Esiste un modo per verificare se un token di accesso è scaduto o valido? ** –

+0

Vedere i campioni quickstart per alcuni codici su come verificare/convalidare i token in modo che non siano solo validi ma anche validi per questo dato utente e app. La verifica dell'app Java lato server può essere vista a partire dalla riga 140: https://github.com/googleplus/gplus-quickstart-java/blob/master/src/com/google/plus/samples/quickstart/Signin.java # L141 – BrettJ

+0

Ehi @BrettJ, questo funzionava per me, ma solo pochi giorni fa ha smesso di funzionare e ora genera questo errore com.google.android.gms.auth.GoogleAuthException: Sconosciuto. Qualche idea del perché? C'è qualcosa di sbagliato nei miei scopi? https://gist.github.com/lawloretienne/7351151 – toobsco42

0

ho avuto il problema simile. Per risolvere il problema con la scadenza del token di accesso, decodifico il token sul lato client e controllo il campo "exp" nel payload del token. In questo modo, posso riconoscere la scadenza del token prima di inviarlo al server. Altri dettagli sono su questo blog post

Problemi correlati