> For the complete documentation index, see [llms.txt](https://docs.opencityitalia.it/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opencityitalia.it/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/le-funzioni/popolare-un-form-con-dati-provenienti-da-api.md).

# Popolare un form con dati provenienti da API

{% hint style="warning" %}
Per utilizzare endpoint API esterni è necessario fare inizialmente riferimento a OpenCity Italia, in modo tale da sbloccare il CSP (Content Security Policy) nel caso in cui l'Ente intenda utilizzare [API non protette da autenticazione](#api-senza-autenticazione) sia [API protette da autenticazione](#api-protette-da-autenticazione).

La funzione può essere utilizzata per recuperare, all'interno del modulo, [dati provenienti da un'altra istanza](/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/le-funzioni/configurare-servizi-a-piu-fasi.md).
{% endhint %}

## Richiedere l'abilitazione del dominio

La piattaforma blocca le chiamate verso domini non autorizzati tramite la **Content Security Policy** (CSP): un meccanismo di sicurezza che controlla da quali origini il browser può caricare risorse esterne.

Per usare un'API esterna in un form, devi prima chiedere al team di OpenCity Italia di autorizzare il dominio. Apri un ticket di supporto e indica:

* il dominio o l'URL base dell'API (es. `https://opendata.comune.example.it`);
* il nome del servizio in cui intendi usarla;
* l'ambiente in cui serve l'abilitazione: produzione, test o entrambi.

{% hint style="info" %}
Richiedi l'abilitazione prima di configurare il componente nel service builder. Finché il dominio non è autorizzato, la select non carica i dati e il modulo risulta non funzionante.
{% endhint %}

Come admin puoi configurare alcuni campi (es. [Select](/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/i-componenti/la-select.md) o [Textfield](/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/i-componenti/il-textfield.md)) in modo tale che vengano compilati con dati presi dalle API.

## Configurare una *select* con dati presi dalle API

Nella sezione "Data" del componente, configura la voce "Data source type" con l'opzione URL

<figure><img src="/files/ExFQPCpIeaDXyzCEpNAR" alt=""><figcaption></figcaption></figure>

Successivamente inserisci l'endpoin API da utilizzare alla voce "Data source url"

<figure><img src="/files/Jgd0gmwsv33De1RuLFZ3" alt=""><figcaption></figcaption></figure>

Alla voce "Storage type" indica il dato da riportare nella select (è consigliabile usare l'opzione "autotype", in modo da predere tutto l'oggetto restituito dall'API)

<figure><img src="/files/xMbbjkcEHYMN2TZ2VHnQ" alt=""><figcaption></figcaption></figure>

Infine, scegli il valore da mostrare alla voce "Item template".

<figure><img src="/files/ojQvJeSOyuhQ0Z34TqNd" alt=""><figcaption></figcaption></figure>

È consigliabile compilare anche il campo "Limit" e indicare un numero massimo di item da visualizzare.

Più alto è il valore indicato più tempo la select ci metterà a caricare gli item; è quindi consigliabile indicare un massimo di 50

<figure><img src="/files/AFZwIHRhWHZ3zboS11GY" alt=""><figcaption></figcaption></figure>

## Configurare un *text field* con i dati presi da API

Nella sezione "Data" del componente, compila la voce "Calculated value" con un codice Json contentente l'URL API:

<div data-full-width="true"><figure><img src="/files/3rhMX2VKV4GezMbbnnYP" alt=""><figcaption></figcaption></figure> <figure><img src="/files/mnbdZiJWmydDdPxN0TNx" alt=""><figcaption></figcaption></figure></div>

Qui trovi un codice di esempio in cui vengono richiamati i dati di un'utenza TARI basandoci sul codice fiscale del richiedente

```json
async function get_data(url, token) {
    try {
        const response = await fetch(url, {
            method: 'GET', 
            headers: {
                'Authorization': `Bearer ${token}`,
                'Content-Type': 'application/json'
            }
        })

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`)
        }

        const data = await response.json() // Parse JSON response
        instance.setValue(data.contract_code)
    } catch (error) {
        instance.setValue("ERRORE")
        console.error('Error fetching data:', error)
        throw error // Optionally re-throw the error for further handling
    }
}

if (!value && data?.applicant?.data.fiscal_code?.data?.fiscal_code && data?.token) {
  get_data(`https://govway.comune.bugliano.pi.it/govway/Ente/TARI/v1/getContractCode.php?cf=${data.applicant.data.fiscal_code.data.fiscal_code}`, data.token)
}
```

## API non protette da autenticazione

Per popolare un form, puoi utilizzare API non protette da autenticazione.

In questo caso, oltre allo sblocco di CSP da parte di OpenCity Italia, è necessario che le API utilizzate siano **pubbliche e raggiungibili**.

## API protette da autenticazione

Dataset e micro servizi esterni alla piattaforma possono essere facilmente integrati tramite il flusso di autenticazione basato su **JWT** (JSON Web Token) e **JWKS** (JSON Web Key Set)

<figure><img src="https://docs.opencityitalia.it/~gitbook/image?url=https%3A%2F%2F2402436129-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252FNwAiDeLoMPCkkp1BdSbI%252Fuploads%252Fph2eSnbsWYF23XlY9npn%252FSchermata%25202024-06-13%2520alle%252013.57.11.png%3Falt%3Dmedia%26token%3Df3127994-bc59-4ed9-aa70-353b743c20c9&#x26;width=768&#x26;dpr=4&#x26;quality=100&#x26;sign=3f952145&#x26;sv=2" alt=""><figcaption><p>Diagramma del flusso di autenticazione con JWT e JWKS</p></figcaption></figure>

Questo flusso di autenticazione prevede alcuni passaggi chiave e interazioni tra:

* **client** (browser dell'utente)
* **area personale**
* **micro servizio esterno**

Di seguito il processo punto per punto:

### **1. Il client richiede il token**

Il client invia una richiesta all'area personale per ottenere un JWT, spesso includendo le credenziali dell'utente o altre forme di autorizzazione.

Come descritto nella sezione [Single Sign-On](https://docs.opencityitalia.it/v/developers/integrazioni/single-sign-on) è possibile per un utente autenticato richiedere un token di autenticazione per la propria sessione.

Questa operazione può essere effettuata facendo una chiamata alle API:

{% embed url="<https://servizi.comune.bugliano.pi.it/lang/api/session-auth>" %}
API per ottenere il token JWT come utente loggato
{% endembed %}

oppure come utente non autenticato effettuando una chiamata POST alle API

{% embed url="<https://servizi.comune.bugliano.pi.it/lang/api/authservizi.comune.bugliano.pi.it>" %}
API per ottenere il token JWT passando le credenziali
{% endembed %}

```sh
curl --request POST \
  --url https://servizi.comune.bugliano.pi.it/lang/api/auth \
  --header 'Content-Type: application/json' \
  --data '{
	"username": "username",
	"password": "password"
}'
```

### **2. L'area personale rilascia il token**

L'area personale autentica il client, genera un JWT e lo firma con una chiave privata.

Il token viene quindi restituito al client.

{% code overflow="wrap" %}

```json
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6InNkYy1xYSJ9.eyJpYXQiO.c2VybmFtZSI6ImFkbWluIiwiaWQiOiI2ZmZkZWRkZi04NmZhLTRjYmEtODUzNC05YTBlNjZmZTNlYmYiLCJ0ZW[...]5hbnRfaWQiOiI2MGUzNWYwMi0xNTA5LTQwOGMtYjEwMS0zYjFhMjgxMDkzMjkifQ.lFe0MR-LAj[...]RjoVvqwk3OX23T642ETu8PUy8sFaVRf1oM1qAnPhLEpnOcrIQY65mpKw6mrJ1rzZM5OVvEeOc4xxmtgcBOfMEBJo_Dw1pMfZHOv2S1S50Zr9XNxk0LcfWjXGdC7wy81eF7UuF-3cX9W"
}
```

{% endcode %}

### **3. Il client richiede la risorsa al micro servizio esterno:**

Il client invia una richiesta al **micro servizio esterno** per accedere a una risorsa protetta, includendo il JWT nell'intestazione Authorization.

```sh
curl --request GET \
  --url '{Url API micro servizio esterno}' \
  --header 'Authorization: Bearer {JWT Token}'
```

### **4. Il micro servizio esterno convalida il token**

Per verificare la validità del token il micro servizio esterno **deve:**

* Estrarre il JWT dalla richiesta
* Recuperare il JWKS dall'area personale, il JWKS contiene le chiavi pubbliche necessarie per verificare la firma del JWT.
* Verificare la firma del JWT e convalidare le sue richieste

{% hint style="info" %}
L'area personale espone il JWKS all'indirizzo:

[`https://api.stanzadelcittadino.it/.well-known/jwks.json`](https://api.stanzadelcittadino.it/.well-known/jwks.json)
{% endhint %}

### **5. Accesso concesso/negato:**

In base alla validità del JWT il micro servizio esterno concede o nega l'accesso alla risorsa richiesta.

Oltre alla validità del token si possono verificare le affermazioni in esso contenute.

Il payload del token prodotto dall'area personale presenta delle informazioni utili a capire se quello specifico utente oltre ad avere un token valido **ha i permessi** per ottenere la risorsa richiesta.

Di seguito un esempio di payload del token

```json
{
  "iat": 1718278670,
  "exp": 1719142670,
  "roles": [
    "ROLE_CPS_USER",
    "ROLE_USER"
  ],
  "username": "BNRMHL75C06G702B",
  "id": "5b00796e-ef10-4c98-b9f5-b0f7ffd7a17d",
  "tenant_id": "60e35f02-1509-408c-b101-3b1a28109329"
}
```

## Un esempio pratico

Qui trovi un esempio dettagliato di un'integrazione di un modulo Opencity Italia che attinge a una API protetta mediante l'API gateway opensource GovWay di Link.it

{% embed url="<https://docs.opencityitalia.it/developers/integrazioni/integrazione-di-un-servizio-di-terze-parti-protetto-da-autenticazione/esempio-con-govway>" %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.opencityitalia.it/guida-alla-creazione-dei-servizi-digitali/creare-un-servizio/le-funzioni/popolare-un-form-con-dati-provenienti-da-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
