OAuth 2.0 per le applicazioni TV e i dispositivi a input limitato

175

Questo documento spiega come implementare l'autorizzazione OAuth 2.0 per accedere alle API di Google tramite applicazioni in esecuzione su dispositivi come TV, console per videogiochi e stampanti. Nello specifico, questo flusso è progettato per i dispositivi che non hanno accesso a un browser o hanno capacità di input limitate.

OAuth 2.0 consente agli utenti di condividere dati specifici con un'applicazione mantenendo privati nomi utente, password e altre informazioni. Ad esempio, un'applicazione TV potrebbe utilizzare OAuth 2.0 per ottenere l'autorizzazione per selezionare un file archiviato su Google Drive.

Poiché le applicazioni che utilizzano questo flusso sono distribuite su singoli dispositivi, si presume che non possano mantenere secret. Possono accedere alle API di Google mentre l'utente è presente nell'app o quando è in esecuzione in background.

Alternative

Se stai scrivendo un'app per una piattaforma come Android, iOS, macOS, Linux o Windows (inclusa la piattaforma Universal Windows), che ha accesso al browser e alle funzionalità di input complete, utilizza il flusso OAuth 2.0 per applicazioni per dispositivi mobili e desktop. Dovresti utilizzare questo flusso anche se la tua app è uno strumento a riga di comando senza un'interfaccia grafica.

Se vuoi solo accedere con i loro Account Google e usare il token ID JWT per ottenere informazioni di base sul profilo utente, vedi Accesso sulle TV e sui dispositivi di input limitati.

Prerequisiti

Abilita le API per il tuo progetto

Qualsiasi applicazione che chiami le API di Google deve abilitarle nel API Console.

Per abilitare un'API per il tuo progetto:

  1. Open the API Library in Google API Console.
  2. If prompted, select a project, or create a new one.
  3. L'elenco API Library elenca tutte le API disponibili, raggruppate per famiglia di prodotti e popolarità. Se l'API che vuoi attivare non è visibile nell'elenco, utilizza la funzione di ricerca per trovarla o fai clic su Visualizza tutto nella famiglia di prodotti a cui appartiene.
  4. Seleziona l'API che vuoi attivare, quindi fai clic sul pulsante Abilita.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Crea credenziali di autorizzazione

Qualsiasi applicazione che utilizzi OAuth 2.0 per accedere alle API di Google deve disporre di credenziali di autorizzazione che identifichino l'applicazione sul server OAuth 2.0 di Google. I passaggi seguenti spiegano come creare le credenziali per il progetto. Le tue applicazioni possono quindi utilizzare le credenziali per accedere alle API che hai abilitato per quel progetto.

  1. Go to the Credentials page.
  2. Fai clic su Crea credenziali > ID client OAuth.
  3. Seleziona il tipo di applicazione TV e dispositivi di input limitati.
  4. Assegna un nome al client OAuth 2.0 e fai clic su Crea.

Identifica gli ambiti di accesso

Gli ambiti consentono all'applicazione di richiedere l'accesso solo alle risorse necessarie, permettendo al tempo stesso agli utenti di controllare la quantità di accesso da loro concessa. Pertanto, potrebbe esserci una relazione inversa tra il numero di ambiti richiesti e la probabilità di ottenere il consenso dell'utente.

Prima di iniziare a implementare l'autorizzazione OAuth 2.0, ti consigliamo di identificare gli ambiti a cui la tua app dovrà avere l'autorizzazione di accesso.

Consulta l'elenco Ambiti consentiti per i dispositivi o le app installate.

Ottenere i token di accesso OAuth 2.0

Anche se l'applicazione viene eseguita su un dispositivo con funzionalità di input limitate, gli utenti devono disporre di accesso separato a un dispositivo con funzionalità di input più avanzate per completare questo flusso di autorizzazione. Il flusso prevede i seguenti passaggi:

  1. La tua applicazione invia una richiesta al server di autorizzazione di Google che identifica gli ambiti ai quali l'applicazione richiederà l'autorizzazione per l'accesso.
  2. Il server risponde con diverse informazioni utilizzate nei passaggi successivi, come un codice dispositivo e un codice utente.
  3. Vengono mostrate informazioni che l'utente può inserire su un dispositivo separato per autorizzare la tua app.
  4. La tua applicazione avvia il polling del server di autorizzazione di Google per determinare se l'utente ha autorizzato l'app.
  5. L'utente passa a un dispositivo con funzionalità di input più avanzate, avvia un browser web, accede all'URL visualizzato nel passaggio 3 e inserisce un codice visualizzato anche nel passaggio 3. L'utente può quindi concedere (o negare) l'accesso alla tua applicazione.
  6. La prossima risposta alla tua richiesta di sondaggio contiene i token necessari per la tua app per autorizzare le richieste per conto dell'utente. Se l'utente ha rifiutato l'accesso all'applicazione, la risposta non contiene token.

L'immagine seguente illustra questa procedura:

L'utente accede a un dispositivo separato dotato di un browser

Queste sezioni spiegano in dettaglio i passaggi descritti di seguito. Data la gamma di funzionalità e ambienti di runtime che possono avere i dispositivi, gli esempi mostrati in questo documento utilizzano l'utilità a riga di comando curl. Questi esempi devono essere facili da trasferire a varie lingue e runtime.

Passaggio 1: richiedi i codici utente e dispositivo

In questo passaggio, il dispositivo invia una richiesta POST HTTP al server di autorizzazione di Google, https://oauth2.googleapis.com/device/code, che identifica la tua applicazione e gli ambiti di accesso a cui l'applicazione vuole accedere per conto dell'utente. Devi recuperare questo URL dal documento di rilevamento utilizzando il valore dei metadati device_authorization_endpoint. Includi i seguenti parametri di richiesta HTTP:

Parametri
client_id Obbligatorio

L'ID client della tua applicazione. Puoi trovare questo valore in API Console Credentials page.

scope Obbligatorio

Un elenco di ambiti delimitati da spazi che identificano le risorse a cui la tua applicazione potrebbe accedere per conto dell'utente. Questi valori informano la schermata di consenso che Google mostra all'utente. Consulta l'elenco Ambiti consentiti per i dispositivi o le app installate.

Gli ambiti consentono all'applicazione di richiedere l'accesso solo alle risorse necessarie e permette agli utenti di controllare la quantità di accesso da concedere all'applicazione. Pertanto, esiste una relazione inversa tra il numero di ambiti richiesti e la probabilità di ottenere il consenso dell'utente.

Esempi

Il seguente snippet mostra una richiesta di esempio:

POST /device/code HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=client_id&scope=

Questo esempio mostra un comando curl per inviare la stessa richiesta:

curl -d "client_id=client_id&scope=" \
     https://oauth2.googleapis.com/device/code

Passaggio 2: gestisci la risposta del server di autorizzazione

Il server di autorizzazione restituirà una delle seguenti risposte:

Risposta riuscita

Se la richiesta è valida, la risposta sarà un oggetto JSON contenente le seguenti proprietà:

Proprietà
device_code Un valore che Google assegna in modo univoco per identificare il dispositivo su cui viene eseguita l'app che richiede l'autorizzazione. L'utente autorizzerà il dispositivo da un altro dispositivo con funzionalità di immissione più avanzate. Ad esempio, un utente potrebbe utilizzare un laptop o un cellulare per autorizzare un'app in esecuzione su una TV. In questo caso, device_code identifica la TV.

Questo codice consente al dispositivo che esegue l'app di stabilire in modo sicuro se l'utente ha concesso o negato l'accesso.

expires_in La durata di tempo, espressa in secondi, in cui device_code e user_code sono validi. Se, in questo lasso di tempo, l'utente non completa la procedura di autorizzazione e il tuo dispositivo non compila il sondaggio per recuperare le informazioni sulla decisione dell'utente, potresti dover riavviare questa procedura dal passaggio 1.
interval Il periodo di tempo, in secondi, durante il quale il dispositivo deve attendere tra una richiesta di sondaggio e l'altra. Ad esempio, se il valore è 5, il tuo dispositivo deve inviare una richiesta di sondaggio al server di autorizzazione di Google ogni cinque secondi. Vedi il passaggio 3 per maggiori dettagli.
user_code Un valore sensibile alle maiuscole che identifica a Google gli ambiti a cui l'applicazione richiede l'accesso. La tua interfaccia utente indicherà all'utente di inserire questo valore su un dispositivo separato con funzionalità di input più avanzate. Google utilizza quindi il valore per visualizzare il set di ambiti corretto quando richiede all'utente di concedere l'accesso all'applicazione.
verification_url Un URL che l'utente deve raggiungere, su un dispositivo separato, per inserire l'elemento user_code e concedere o negare l'accesso alla tua applicazione. L'interfaccia utente mostrerà questo valore.

Il seguente snippet mostra una risposta di esempio:

{
  "device_code": "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
  "user_code": "GQVQ-JKEC",
  "verification_url": "https://www.google.com/device",
  "expires_in": 1800,
  "interval": 5
}

La quota ha superato la risposta

Se le richieste del codice del dispositivo hanno superato la quota associata al tuo ID client, riceverai una risposta 403 contenente il seguente errore:

{
  "error_code": "rate_limit_exceeded"
}

In tal caso, utilizza una strategia di backoff per ridurre la percentuale di richieste.

Passaggio 3: visualizza il codice utente

Mostra all'utente i valori verification_url e user_code ottenuti nel passaggio 2. Entrambi i valori possono contenere qualsiasi carattere stampabile del set di caratteri ASCII USA. Il contenuto che mostri all'utente deve indicare a verification_url su un dispositivo separato e inserire il user_code.

Progetta l'interfaccia utente (UI) tenendo presenti le seguenti regole:

  • user_code
    • user_code deve essere visualizzato in un campo in grado di gestire caratteri di dimensione pari a 15 & W3#. In altre parole, se riesci a visualizzare il codice WWWWWWWWWWWWWWW correttamente, l'interfaccia utente è valida e ti consigliamo di utilizzare tale valore stringa durante il test del modo in cui user_code mostra nell'interfaccia.
    • Il testo user_code fa distinzione tra maiuscole e minuscole e non deve essere modificato in modo tale da consentire la modifica di maiuscole/minuscole o l'inserimento di altri caratteri di formattazione.
  • verification_url
    • Lo spazio in cui visualizzi verification_url deve essere abbastanza ampio da gestire una stringa URL di 40 caratteri.
    • Non modificare in alcun modo verification_url, tranne se vuoi rimuovere lo schema per la visualizzazione. Se prevedi di rimuovere lo schema (ad esempio https://) dall'URL per motivi di visualizzazione, assicurati che la tua app possa gestire entrambe le varianti http e https.

Passaggio 4: interroga il server di autorizzazione di Google

Poiché l'utente utilizzerà un dispositivo separato per passare all'verification_url e concedere (o negare) l'accesso, il dispositivo richiedente non riceve automaticamente la notifica quando l'utente risponde alla richiesta di accesso. Per questo motivo, il dispositivo richiedente deve eseguire il polling del server di autorizzazione di Google per determinare quando l'utente ha risposto alla richiesta.

Il dispositivo richiedente deve continuare a inviare richieste di polling finché non riceve una risposta che indica che l'utente ha risposto alla richiesta di accesso o fino alla scadenza dei device_code e di user_code nel passaggio 2. interval restituito nel passaggio 2 specifica la quantità di tempo, in secondi, per attendere tra una richiesta e l'altra.

L'URL dell'endpoint al sondaggio è https://oauth2.googleapis.com/token. La richiesta di sondaggio contiene i seguenti parametri:

Parametri
client_id L'ID client della tua applicazione. Puoi trovare questo valore in API Console Credentials page.
client_secret Il client secret per l'elemento client_id fornito. Puoi trovare questo valore in API Console Credentials page.
device_code Il device_code restituito dal server di autorizzazione nel passaggio 2.
grant_type Imposta urn:ietf:params:oauth:grant-type:device_code per questo valore.

Esempi

Il seguente snippet mostra una richiesta di esempio:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=client_id&
client_secret=client_secret&
device_code=device_code&
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code

Questo esempio mostra un comando curl per inviare la stessa richiesta:

curl -d "client_id=client_id&client_secret=client_secret& \
         device_code=device_code& \
         grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code" \
         -H "Content-Type: application/x-www-form-urlencoded" \
         /token

Passaggio 5: l'utente risponde alla richiesta di accesso

L'immagine seguente mostra una pagina simile a quella che vedono gli utenti quando accedono al verification_url che hai visualizzato nel passaggio 3:

Collega un dispositivo inserendo un codice

Dopo aver inserito user_code, l'utente visualizza una schermata di consenso come quella mostrata di seguito, se non ha ancora eseguito l'accesso a Google:

Schermata di consenso di esempio per un client dispositivo

Passaggio 6: gestisci le risposte alle richieste di sondaggio

Il server di autorizzazione di Google risponde a ogni richiesta di sondaggio con una delle seguenti risposte:

Accesso accordato

Se l'utente ha concesso l'accesso al dispositivo (facendo clic su Allow nella schermata di consenso), la risposta contiene un token di accesso e un token di aggiornamento. I token consentono al dispositivo di accedere alle API di Google per conto dell'utente. La proprietà scope nella risposta determina a quali API può accedere il dispositivo.

In questo caso, la risposta dell'API contiene i seguenti campi:

Campi
access_token Il token che la tua applicazione invia per autorizzare una richiesta API di Google.
expires_in La durata rimanente del token di accesso in secondi.
refresh_token Un token che puoi utilizzare per ottenere un nuovo token di accesso. I token di aggiornamento sono validi finché l'utente non revoca l'accesso. Tieni presente che i token di aggiornamento vengono sempre restituiti per i dispositivi.
scope Gli ambiti di accesso concessi da access_token espressi come elenco di stringhe sensibili alle maiuscole.
token_type Il tipo di token restituito. Al momento, il valore di questo campo è sempre impostato su Bearer.

Il seguente snippet mostra una risposta di esempio:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
  "token_type": "Bearer",
  "refresh_token": "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

I token di accesso hanno una durata limitata. Se la tua applicazione ha bisogno di accedere a un'API per un lungo periodo di tempo, può utilizzare il token di aggiornamento per riceverne uno nuovo. Se la tua applicazione necessita di questo tipo di accesso, dovrà archiviare il token di aggiornamento per un utilizzo futuro.

Accesso negato

Se l'utente rifiuta di concedere l'accesso al dispositivo, la risposta del server ha un 403 codice di stato di risposta HTTP (Forbidden). La risposta contiene il seguente errore:

{
  "error": "access_denied",
  "error_description": "Forbidden"
}

In attesa di autorizzazione

Se l'utente non ha ancora completato il flusso di autorizzazione, il server restituisce un codice di stato di risposta HTTP 428 (Precondition Required). La risposta contiene il seguente errore:

{
  "error": "authorization_pending",
  "error_description": "Precondition Required"
}

Sondaggi troppo frequenti

Se il dispositivo invia richieste di polling troppo spesso, il server restituisce un codice di stato di risposta HTTP 403 (Forbidden). La risposta contiene il seguente errore:

{
  "error": "slow_down",
  "error_description": "Forbidden"
}

Altri errori

Il server di autorizzazione restituisce anche errori se nella richiesta di sondaggio mancano parametri obbligatori o un valore parametro non corretto. Queste richieste di solito hanno un codice di stato risposta HTTP 400 (Bad Request) o 401 (Unauthorized). Tali errori includono:

Errore Codice di stato HTTP Description
invalid_client 401 Impossibile trovare il client OAuth. Ad esempio, questo errore si verifica se il valore parametro client_id non è valido.
invalid_grant 400 Il valore parametro code non è valido.
unsupported_grant_type 400 Il valore parametro grant_type non è valido.

Chiamata delle API di Google

Dopo che l'applicazione ha ottenuto un token di accesso, puoi utilizzarlo per effettuare chiamate a un'API Google per conto di un determinato account utente se sono stati concessi gli ambiti di accesso richiesti dall'API. A tale scopo, includi il token di accesso in una richiesta all'API includendo un parametro di ricerca access_token o un valore Bearer dell'intestazione HTTP Authorization. Se possibile, è preferibile l'intestazione HTTP, perché le stringhe di query tendono a essere visibili nei log del server. Nella maggior parte dei casi puoi utilizzare una libreria client per configurare le chiamate alle API di Google (ad esempio, quando chiami l'API Drive Files).

Puoi provare tutte le API di Google e visualizzarne gli ambiti in OAuth 2.0 Playground.

Esempi GET HTTP

Una chiamata all'endpoint drive.files (l'API Drive File) che utilizza l'intestazione HTTP Authorization: Bearer potrebbe avere il seguente aspetto. Tieni presente che devi specificare il tuo token di accesso:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Ecco una chiamata alla stessa API per l'utente autenticato utilizzando il parametro della stringa di query access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

Esempi di curl

Puoi testare questi comandi con l'applicazione a riga di comando curl. Ecco un esempio che utilizza l'opzione di intestazione HTTP (opzione preferita):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

In alternativa, puoi scegliere l'opzione del parametro della stringa di query:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Aggiornamento di un token di accesso

I token di accesso scadono periodicamente e diventano credenziali non valide per una richiesta API correlata. Puoi aggiornare un token di accesso senza chiedere l'autorizzazione all'utente (anche quando non è presente) se hai richiesto l'accesso offline agli ambiti associati al token.

Per aggiornare un token di accesso, l'applicazione invia una richiesta HTTPS POST al server di autorizzazione di Google (https://oauth2.googleapis.com/token) che include i seguenti parametri:

Campi
client_id L'ID client ottenuto da API Console.
client_secret Il client secret ottenuto da API Console.
grant_type Come definito nella specifica OAuth 2.0, il valore di questo campo deve essere impostato su refresh_token.
refresh_token Il token di aggiornamento restituito dallo scambio di codice di autorizzazione.

Il seguente snippet mostra una richiesta di esempio:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=your_client_id&
client_secret=your_client_secret&
refresh_token=refresh_token&
grant_type=refresh_token

Se l'utente non ha revocato l'accesso concesso all'applicazione, il server token restituisce un oggetto JSON contenente un nuovo token di accesso. Il seguente snippet mostra una risposta di esempio:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "token_type": "Bearer"
}

Tieni presente che esiste un limite al numero di token di aggiornamento che verranno emessi: un limite per combinazione client/utente e un altro per utente in tutti i client. Dovresti salvare i token di aggiornamento nello spazio di archiviazione a lungo termine e continuare a utilizzarli finché rimangono validi. Se la tua applicazione richiede troppi token di aggiornamento, questi potrebbero superare questi limiti. In questo caso, i token di aggiornamento meno recenti smetteranno di funzionare.

Revoca di un token

In alcuni casi, un utente potrebbe voler revocare l'accesso concesso a un'applicazione. Un utente può revocare l'accesso visitando le impostazioni dell'account. Per ulteriori informazioni, consulta la sezione Rimuovere il sito o l'accesso alle app del sito di terze parti e delle app con accesso al tuo account.

È inoltre possibile che un'applicazione revochi in modo programmatico l'accesso concesso. La revoca programmatica è importante nei casi in cui un utente annulla l'iscrizione, rimuove un'applicazione o le risorse API richieste dall'app sono cambiate in modo significativo. In altre parole, una parte del processo di rimozione può includere una richiesta API per garantire la rimozione delle autorizzazioni precedentemente concesse all'applicazione.

Per revocare un token in modo programmatico, l'applicazione invia una richiesta a https://oauth2.googleapis.com/revoke e include il token come parametro:

curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
        https://oauth2.googleapis.com/revoke?token={token}

Il token può essere un token di accesso o un token di aggiornamento. Se è un token di accesso e ha un token di aggiornamento corrispondente, verrà revocato anche il token di aggiornamento.

Se la revoca viene elaborata correttamente, il codice di stato HTTP della risposta è 200. Per le condizioni di errore, viene restituito un codice di stato HTTP 400 insieme a un codice di errore.

Ambiti consentiti

Il flusso OAuth 2.0 per i dispositivi è supportato solo per i seguenti ambiti:

OpenID Connect, Accedi con Google

  • email
  • openid
  • profile

API Drive

  • https://www.googleapis.com/auth/drive.appdata
  • https://www.googleapis.com/auth/drive.file

API di YouTube

  • https://www.googleapis.com/auth/youtube
  • https://www.googleapis.com/auth/youtube.readonly