> This page is for Piattaforma, version Versione precedente.
> For other versions, use one of these documentation indexes:
> - V4 (default): https://next.developer.frame.io/platform/v4/llms.txt
> - V4 sperimentale: https://next.developer.frame.io/platform/v4-experimental/llms.txt
> - Versione precedente: https://next.developer.frame.io/platform/v2/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# Guida pratica: Autorizzazione (applicazione)

## Introduzione

In questa guida imparerai ad autenticare e autorizzare un'*applicazione C2C* in un progetto [Frame.io](http://frame.io/).

## Cosa serve?

Se non hai letto la guida [Implementazione C2C: configurazione](/camera-to-cloud/implementing-c2c-setting-up), dalle un'occhiata veloce prima di continuare!Inoltre, dovresti aver ricevuto dal nostro team un `client_id` che sarà utilizzato per identificare la tua integrazione.Se non hai ricevuto un `client_id`, leggi [questa introduzione](/camera-to-cloud/getting-started-with-cloud-device-integrations) all'ecosistema C2C e contatta il nostro team.Se hai ricevuto un `client_secret` invece di un `client_id`, ti abbiamo configurato come dispositivo hardware anziché come applicazione C2C. Dovrai seguire la [guida all'autorizzazione per dispositivi hardware](/platform/v2/implementing-c2c-authentication-and-authorization-hardware) oppure contattare il nostro team per ricevere un `client_id`.

## Guida al flusso di autorizzazione dell'applicazione

Assicuriamoci di avere una comprensione generale dell'esperienza utente prevista per il flusso di autorizzazione che vogliamo implementare.Consulta le seguenti risorse per vedere questo flusso dal punto di vista dell'utente. Prova a scaricare [Zoelog](https://zoelog.io/) e ad accedere a [Frame.io](http://frame.io/) per capire come funziona il processo di autorizzazione per le applicazioni C2C.

## Panoramica di OAuth

Le applicazioni C2C usano un flusso OAuth 2.0 per l'autenticazione e l'autorizzazione. Si tratta di un insieme standardizzato di chiamate che può essere utilizzato per autenticare e autorizzare un'applicazione o un utente di terze parti per un servizio. Puoi [trovare altre informazioni sul flusso OAuth qui](https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2).

## URI di callback/reindirizzamento

Come parte del flusso OAuth, i nostri server dovranno effettuare una chiamata HTTP a un URI/URL che sei tu a controllare. Dopo che un utente accede a [Frame.io](http://frame.io/) nel browser, reindirizziamo il browser a questo URI per fornire alcune informazioni alla tua applicazione. L'URI di reindirizzamento deve essere:
* Di tua proprietà
* Statico




Puoi avere più di un reindirizzamento valido registrato per il tuo dispositivo, purché soddisfino questi due criteri.





Durante il flusso OAuth, verifichiamo che l'URI di callback richiesto dall'applicazione sia uno degli URI che abbiamo in archivio. Se non lo è, il flusso di autorizzazione non riesce. Se non effettuassimo questo controllo, un malintenzionato potrebbe fornire un reindirizzamento a un indirizzo che controlla.

Per scopi di sviluppo, supportiamo i callback non HTTPS su `http://localhost`.

## Identificazione del dispositivo





Al momento di connettersi a Camera to Cloud, ogni singola installazione di app deve identificarsi in modo univoco affinché sia possibile elencare le connessioni dei dispositivi nel progetto di un utente.

Per le applicazioni C2C, questo sarà il `device_id` del dispositivo. Quando configuri l'implementazione, devi pensare a come farlo. Alcune piattaforme offrono un'API per generare un identificatore specifico per dispositivo e app per questo caso d'uso esatto:
| PIATTAFORMA | RIFERIMENTO |
|---	|---	|
| iOS | [identifierForVendor](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor) |
| Android | [FID o GUID](https://developer.android.com/training/articles/user-data-ids) |



<Warning title="Fai attenzione a non divulgare informazioni di identificazione personale">
  L'e-mail dell'utente, ad esempio, non è un valore valido da utilizzare come `device_id`. Allo stesso modo, *assicurati di possedere l'identificatore univoco*. Non utilizzare l'indirizzo MAC del dispositivo, ad esempio. L'indirizzo MAC non è di proprietà del tuo software e potrebbe anche essere considerato un'informazione di identificazione personale.
</Warning>


Se non sei sicuro del valore che vorresti utilizzare, possiamo discutere insieme questa scelta e assicurarci che venga scelto un valore adatto, in grado di semplificare il più possibile l'integrazione.





## Passaggio 1: autenticazione dell'utente

Al momento di connettersi a [Frame.io](http://frame.io/) in *LaTuaApp™*, occorre andare alla sezione di configurazione [Frame.io](http://frame.io/) e selezionare &quot;Connetti al progetto&quot; (o qualcosa di simile). Quando si fa clic sul pulsante, l'utente viene reindirizzato a [Frame.io](http://frame.io/) per accedere e autorizzare l'app.

Per farlo, viene creato un URL che viene aperto in un browser web. Diamo un'occhiata allo pseudocodice simile a Python:





**`Python`**

```python title="Python"
def redirect_to_auth(config):
    credentials = {
        "response_type": "code",
        "redirect_uri": "http://MyApp.io/frameio-callback",
        "client_id": f"{MYAPP.client_id}",
        "scope": "offline device.connect asset.create",
        "state": str(uuid.uuid4()),
        "device_id": f"{HARDWARE.get_vendor_id('com.mycompany.myapp')}",
    }

    encoded = parse.urlencode(credentials)
    url = "https://applications.frame.io/oauth2/auth?" + encoded

    webbrowser.open(url)
```





Il nostro &quot;payload&quot; è codificato nell'URL stesso e, se è codificato completamente, l'URL avrà un aspetto simile a questo:





```text
https://applications.frame.io/oauth2/auth?response_type=code&redirect_uri=http%3A%2F%2FMyApp.io%2Fframeio-callback&client_id=[client_id]&scope=offline+device.connect+asset.create&state=[state]&device_id=62f88d2a-1ae1-45e7-a6a0-81954e0cf2ff
```





Analizziamo queste opzioni:

`response_type`: il tipo di risposta del flusso Oauth. Questo valore deve essere sempre &quot;code&quot;. Indica al server Oauth di inviare un codice all'URI di reindirizzamento, che verrà quindi usato per recuperare i token di autorizzazione effettivi. `redirect_uri`: URL/URI in cui il server Oauth deve eseguire una richiesta GET quando risponde a una richiesta di autenticazione. `client_id`: identifica la tua applicazione. Per le integrazioni delle applicazioni, questo valore verrà fornito da Frame.io. `scope`: elenco di autorizzazioni delimitate da spazi che l'applicazione sta richiedendo. Per le applicazioni C2C sono disponibili le seguenti autorizzazioni
* `offline`: l'app può aggiornare la propria autorizzazione quando il token iniziale scade.
* `device.connect`: il dispositivo può ottenere un elenco di account e progetti disponibili per le connessioni C2C dall'utente.
* `asset.create`: l'app può caricare risorse nei progetti a cui è connessa.




Anche se è possibile richiedere e ottenere un sottoinsieme di questi ambiti, conviene sempre richiederli tutti e tre.

`state`: valore casuale associato a questa richiesta. `state` viene utilizzato per verificare che le chiamate all'URI di reindirizzamento siano per richieste valide. Quando ricevi una callback sull'URI registrato, devi verificare che lo stato (`state`) sia quello previsto.
<Warning title="">
  Il valore di &quot;state&quot; deve essere casuale. Se il parametro &quot;state&quot; non è casuale, ti esponi agli attacchi CRSF, in cui un malintenzionato falsifica il parametro &quot;state&quot; e invia una richiesta dannosa al callback. Puoi leggere di più sul parametro `state` in [questo blog di Auth0](https://auth0.com/docs/secure/attack-protection/state-parameters)
</Warning>
 `device_id`: identificatore univoco per il dispositivo o l'installazione. L'ID dispositivo deve essere un valore *di tua proprietà* (quindi non un indirizzo MAC o un numero di serie di CPU ecc.) e *non deve contenere informazioni personalmente identificabili* (quindi nessun indirizzo e-mail, codice fiscale, hash di impronte digitali ecc.). Consulta la [sezione precedente sul device_id](/platform/v2/implementing-c2c-authentication-and-authorization-c2c-application#device-identification-device_id) per maggiori informazioni.

## Passaggio 2: ricezione della risposta OAuth

Dopo che l'utente ha effettuato l'accesso a [Frame.io](http://frame.io/) e ha accettato gli ambiti richiesti nel browser, viene inviata una richiesta GET al tuo URI di callback. La richiesta contiene un payload codificato con URL che ha i seguenti parametri di richiesta. `code`: un codice che verrà usato per recuperare i token di autorizzazione effettivi dal backend di Frame.io. `state`: il valore dello stato incluso nella richiesta di autenticazione originale nel passaggio 1. `scope`: le autorizzazioni e gli ambiti concessi.

L'URI completo avrà un aspetto simile a questo:





```text
https://MyApp.io/frameio-callback?code=[authorization_code]&scope=offline+device.connect+asset.create&state=[state]
```





L'analisi degli URI può essere complessa e la libreria HTTP/server probabilmente dispone di buone risorse per farlo, quindi dai un'occhiata prima di decidere di provare ad analizzare questo valore in modo indipendente!

Per il test, possiamo configurare rapidamente un server per osservare la richiesta GET usando Python. L'URI di callback deve essere configurato come `http://localhost:8888/callback`

```shell
$ python -m http.server 8888
```

Ora possiamo utilizzare il seguente modello per richiedere l'accesso a [Frame.io](http://frame.io/). Inserisci il tuo `[client_id]` e un valore per `[state]`. Puoi [generare un UUID casuale qui](https://www.uuidgenerator.net/) per `state`.

```text
https://applications.frame.io/oauth2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fcallback&client_id=[client_id]&scope=offline+device.connect+asset.create&state=[state]&device_id=62f88d2a-1ae1-45e7-a6a0-81954e0cf2ff
```





Quando passiamo attraverso il flusso di autenticazione, otteniamo un errore 404. Questo accade perché Python non riconosce la risorsa richiesta e non sa come rispondere. Ma non preoccuparti, la richiesta di autenticazione è comunque riuscita! Dovremmo vedere che il server stampa qualcosa del genere nel terminale:





```text
Serving HTTP on :: port 8888 (http://[::]:8888/) ...
::1 - - [08/Mar/2022 14:04:34] code 404, message File not found
::1 - - [08/Mar/2022 14:04:34] "GET /callback?code=[authentication_code]&scope=offline+device.connect+asset.create&state=[state] HTTP/1.1" 404 -
```

Dobbiamo verificare che lo stato sia lo stesso che abbiamo inviato. Il valore di . `authentication_code` sarà importante nel passaggio successivo per recuperare i token di accesso.

In un'app reale, un gestore di callback potrebbe apparire così:





**`Python`**

```python title="Python"
@handler("/frameio-callback")
def do_get(request):
    params = url.parse_query(request.url.parts.query)
    if "error" in params:
       raise AuthError(params["error"])

    # Handles sending the authentication code and state to the proper user
    MyApp.frameio_oauth_success(state=params["state"], code=params["code"])

    # Render some sort of confirmation page for the user.
    request.send_response(
        code=200, 
        headers={"Content-type": "text/html"}, 
        data=OauthSuccessPage()
    )

```





## Passaggio 3: recupero dei token di accesso

Ora che abbiamo l'`authorization_code`, possiamo recuperare il token di accesso! A questo punto, il token di accesso è già stato concesso, dobbiamo solo richiederlo al backend.

Facciamo la seguente richiesta:





```shell
curl -X POST https://applications.frame.io/oauth2/token \
    --form 'client_id=[client_id]' \
    --form 'state=[state]' \
    --form 'code=[authorization_code]' \
    --form 'redirect_uri=http://localhost:8888/callback' \
    --form 'grant_type=authorization_code' \
    --form 'scope=offline device.connect asset.create' \
    | python -m json.tool
```




<Info title="Endpoint OAuth">
  L'host per questa richiesta è `applications.frame.io`, anziché `api.frame.io`, che usiamo per la maggior parte delle richieste. Tieni presente che stiamo utilizzando dati del modulo, invece di dati JSON. *Gli endpoint di OAuth C2C accettano solo dati di modulo.*
</Info>
 Una volta autenticato, altri endpoint accettano il payload `application/json`, ma gli endpoint di autenticazione restituiscono un errore se invii JSON anziché dati `application/x-www-form-urlencoded`.

Esaminiamo questi parametri:

`client_id`: l'identificatore dell'app Oauth che è stato rilasciato da [Frame.io](http://frame.io/) `state`: il valore di stato che abbiamo incluso nella nostra richiesta di autorizzazione originale al browser e ricevuto nel callback. `code`: il codice di autorizzazione ricevuto nel callback `redirect_uri`: lo stesso URI di reindirizzamento registrato con il backend di Frame.io. Se questo valore non è nell'elenco degli URL separati da virgole che [Frame.io](http://frame.io/) ha registrato per l'integrazione, questa richiesta non riuscirà. `grant type`: per il flusso di autorizzazione del dispositivo software, sarà sempre `authorization_code`. `scope`: deve corrispondere agli ambiti approvati restituiti nel callback.

Dovremmo ricevere una risposta simile a questa:





```json
{
    "access_token": "[access_token]",
    "expires_in": 3599,
    "refresh_token": "[refresh_token]",
    "scope": "offline device.connect asset.create",
    "token_type": "bearer"
}
```





Il dispositivo è ora autorizzato in Frame.io! Tieni a portata di mano questi valori perché serviranno per eseguire il resto delle richieste. Vediamo cosa c'è nel payload:

`access_token`: questa è la tua chiave per il resto del backend [Frame.io](http://frame.io/).Dovrà essere aggiunto all'intestazione delle altre richieste che faremo in queste esercitazioni.`expires_in`: il numero di secondi fino alla scadenza di `access_token`.Una volta scaduto il token, dovrà essere aggiornato. Tratteremo questo argomento in un'esercitazione futura.`refresh_token`: un token che possiamo utilizzare per gestire il nostro `access_token`.Verrà utilizzato principalmente per aggiornare l'autorizzazione, ma può anche essere utilizzato per revocarla.`token_type`: sarà sempre `bearer` per l'API C2C e non è operativo.

Ci sono ancora alcuni passaggi prima di stabilire effettivamente la connessione a un progetto, perciò continuiamo!





## Passaggio 4: elenca gli account





Ora dobbiamo ottenere un elenco degli account a cui l'utente può connettersi. Questa è la prima chiamata che richiede il token di accesso e lo aggiungeremo a un'intestazione:





```shell
curl -X GET https://api.frame.io/v2/devices/accounts \
    --header "x-client-version: 2.0.0" \
    --header "Authorization: Bearer [access_token]" \
    | python -m json.tool
```




<Info title="Specifica dell'endpoint API">
  La documentazione per `/v2/devices/accounts` è [disponibile qui](/camera-to-cloud/api-reference/applications-auth/device-list-accounts)
</Info>

<Info title="L'intestazione Authorization">
  Per ogni endpoint che richiede l'autorizzazione, dobbiamo aggiungere `access_token` all'intestazione `Authorization`. Tieni presente che dobbiamo anteporre `Bearer ` (con uno spazio!) al nostro token di accesso come valore.
</Info>


Questa chiamata dovrebbe restituire un elenco di account a cui l'utente può connettersi:





```json
[
    {
        "_type": "account",
        "display_name": "Hogwarts General",
        "id": "46b7ea11-3041-4e2b-97f7-98fbf5c974c9"
    },
    {
        "_type": "account",
        "display_name": "Gryffindor",
        "id": "e6007a3d-cad7-4666-9ee3-23c1af032060"
    },
    {
        "_type": "account",
        "display_name": "QUIDDITCH LEGENDS -- LETS GOOOOOOOOOO",
        "id": "cc94119d-f957-4d6e-b8cf-0c095211b1b9"
    }
]
```

A questo punto, mostri questo elenco all'utente e gli fai selezionare l'account a cui desidera connettersi. Utilizziamo l'`id` dell'account nel passaggio successivo per elencare i progetti ai quali l'utente può connettere un dispositivo C2C.

## Passaggio 5: elenca i progetti





Ora dobbiamo ottenere un elenco di progetti per l'account che ci interessa:





```shell
curl -X GET https://api.frame.io/v2/devices/accounts/[account_id]/projects \
    --header "x-client-version: 2.0.0" \
    --header "Authorization: Bearer [access_token]" \
    | python -m json.tool
```




<Info title="Specifica dell'endpoint API">
  La documentazione per `/v2/devices/accounts/[account_id]/projects` è [disponibile qui](/camera-to-cloud/api-reference/applications-auth/device-list-projects)
</Info>
 Dobbiamo aggiungere l'`account_id` per cui stiamo cercando di elencare i progetti all'URL. Inoltre, nota che il percorso complessivo della risorsa inizia con `/devices/...`. Qui non stiamo solo elencando progetti, ma stiamo elencando i progetti *per i quali l'utente ha autorizzazioni di gestione dei dispositivi C2C*. Se un progetto a cui appartiene l'utente non è elencato, significa che non ha autorizzazioni di gestione dispositivi C2C per quel progetto.

Otterremo una risposta simile a quella per gli account:





```json
[
    {
        "_type": "project",
        "id": "921480ec-1225-424a-9447-19c61a3a1ef2",
        "name": "Match Recordings"
    },
    {
        "_type": "project",
        "id": "ed5dbf4a-f146-416b-add0-74de98201876",
        "name": "Year Book Material"
    }
]
```

Proprio come per gli account, questo elenco dovrebbe essere mostrato all'utente in modo che selezioni il progetto a cui desidera connettersi. Proprio come per gli account, avremo bisogno dell'`id` del progetto per il passaggio successivo.

## Passaggio 6: connessione a un progetto

Ora che l'utente ha selezionato il progetto a cui desidera connettersi, è tutto pronto! C'è solo un ultimo passaggio per completare l'associazione del nostro dispositivo software a un progetto [Frame.io](http://frame.io/):

```shell
curl -X POST https://api.frame.io/v2/devices/connect?project_id={project_id} \
    --header "x-client-version: 2.0.0" \
    --header "Authorization: Bearer [access_token]" \
    | python -m json.tool
```




<Info title="Specifica dell'endpoint API">
  La documentazione per `/v2/devices/connect` è [disponibile qui](/camera-to-cloud/api-reference/applications-auth/device-project-connect)
</Info>


L'ID del progetto è un parametro di query dell'URL e dobbiamo ancora passare la nostra intestazione di autorizzazione!





Otteniamo una risposta come questa (alcuni dati sono stati omessi per brevità):





```json
{
    "_type": "project_device",
    "asset_type": "video",
    "authorization": {
        "_type": "project_device_authorization",
        "creator": {
            "_type": "user",
            "account_id": "93f872fb-9924-4e31-a430-2574e0742260",
            "deleted_at": null,
            "email": "hpotter@hoggyhoggyhogwarts.edu",
            "id": "d473b5e1-08d2-4842-82ac-a6b01233dc2c",
            ...
            "name": "Harry Potter",
            ...
        },
        "creator_id": "d473b5e1-08d2-4842-82ac-a6b01233dc2c",
        "expires_at": null,
        "id": "ee9f5949-b7fa-4c71-8480-6d4c60877c51",
        "inserted_at": "2022-03-09T18:14:21.893283Z",
        "project_device_id": "6a55d7f6-dfb7-46a1-bff8-a3acb2d3d1aa",
        "scopes": {
            ...
            "asset_create": true,
            ...
            "id": "1e174fe9-5b53-48db-b556-c310c0848898",
            "offline": true,
            ...
        }
    },
    "channels": [
        {
            "_type": "project_device_channel",
            "asset_type": "video",
            ...
        }
    ],
    "creator_id": "d473b5e1-08d2-4842-82ac-a6b01233dc2c",
    "deleted_at": null,
    "device_id": "a8a4f3bf-196c-4748-832b-28f1d0801515",
    "id": "93af90e7-ee89-4b47-86e6-c2750f3790b6",
    ...
    "name": "MyApp-62f88d2a-1ae1-45e7-a6a0-81954e0cf2ff",
    "project": {
        "_type": "project",
        "id": "921480ec-1225-424a-9447-19c61a3a1ef2",
        "name": "Testbed"
    },
    "project_id": "921480ec-1225-424a-9447-19c61a3a1ef2",
    "status": "online",
    ...
}
```




<Info title="Un progetto alla volta">
  


Puoi associare un dispositivo a un solo progetto alla volta ed eseguire un'altra operazione di associazione a un progetto diverso ne rimuoverà la connessione con quello precedentemente connesso.



</Info>


Se il payload della risposta è simile a questo,Ce l'hai fatta! Hai autorizzato il tuo primo dispositivo Camera to Cloud.È il momento di festeggiare!





Quando hai finito di festeggiare, dovresti mostrare il nome del progetto all'utente per verificare il progetto a cui si è connesso.





## Utilizzo di una libreria OAuth di terze parti

[Frame.io](http://frame.io/) utilizza il flusso Oauth2.0 standard. Per motivi di sicurezza, applichiamo PKCE. Esistono molte librerie per gestire questa parte dell'integrazione al posto tuo.

Ecco alcune librerie Oauth popolari:




| Linguaggio di programmazione | Nome | URL |
|---	|---	|---	|
| Swift | `OAuthSwift` | [Github](https://github.com/OAuthSwift/OAuthSwift) |
| Python | `requests-oauthlib` | [Github](https://github.com/requests/requests-oauthlib) |
| Flutter | `oauth2_client` | [Github](https://pub.dev/packages/oauth2_client) |
Ricorda che [Frame.io](http://frame.io/) aggiunge un campo `device_id` per identificare un particolare dispositivo. Si tratta di un campo personalizzato aggiuntivo. La libreria che scegli di utilizzare avrà molto probabilmente il supporto per i campi personalizzati, ma assicurati di aggiungerlo!

## Risoluzione dei problemi

Se sei qui, allora qualcosa è andato storto!Cosa sarebbe l'integrazione con una terza parte senza qualche tipo di errore?Questa sezione elenca una serie di problemi comuni e ti guida attraverso i passaggi più probabili per risolverli.Dai un'occhiata all'elenco in basso e verifica se qualcosa corrisponde al tuo problema. Anche la [guida agli errori](/camera-to-cloud/how-to-handle-errors) è un'ottima risorsa per cercare gli errori dell'API.

Se non trovi una soluzione qui, ci farebbe molto piacere conoscere il problema che hai riscontrato per poterlo aggiungere qui!

**L'account o il progetto a cui voglio connettermi non è stato restituito:** se stai elencando account e/o progetti e quello a cui vuoi connetterti non è presente nell'elenco, potrebbero essersi verificate una paio di cose. In Frame.io, vai al progetto a cui vuoi connetterti e dai clic sulla scheda `Connessioni C2C`.Ciò è utile per capire cosa non va.
* **C2C non è abilitato per il tuo account:** se la schermata è vuota e compare un messaggio che dice che C2C non è disponibile per il tuo account, il gestore dell'account deve attivarlo per il tuo progetto nelle impostazioni dell'account.
* **Non sei un gestore del dispositivo**: se la schermata è vuota e compare un messaggio che dice che non hai le autorizzazioni, il gestore dell'account deve cambiare le autorizzazioni per stabilire chi può connettere i dispositivi C2C oppure aggiungerti a un ruolo che ha quelle autorizzazioni.

**Errore di client non valido:** viene restituito `invalid_client` quando le informazioni che ci stai fornendo sul dispositivo non corrispondono a quelle registrate. Molto probabilmente significa che il tuo `client_secret`, `client_id` o `redirect_uri` non corrispondono a quanto registrato da Frame.io negli archivi backend. **Errore di richiesta non valida:** viene restituito `bad_request` quando i dati della richiesta sono in un formato errato. Controlla di non aver scritto male il nome di un campo o di non aver dimenticato di aggiungere un campo obbligatorio.

## Avanti





Se non l'hai già fatto, ti incoraggiamo a contattare il nostro team, poi continua con la prossima guida.A presto!