Flusso Native Application
Usa il flusso Native app per integrazioni che agiscono per conto di un utente che ha effettuato l’accesso dalla propria macchina, come un’app desktop, una CLI o un plugin CAD. Usa Authorization Code con PKCE, un redirect loopback su localhost e nessun client secret. Questa guida ti accompagna nella configurazione dalla creazione dell’applicazione OAuth alla tua prima chiamata all’API.
Rivedi prima la guida Per iniziare se non hai ancora coperto i prerequisiti, l’accesso di rete e il modello di sicurezza.
Cosa farai
Sezione intitolata “Cosa farai”- Creare un’applicazione OAuth: registra un’app nativa in Prevu3D e ottieni un Client ID
- Configurare l’accesso dell’utente: assicurati che l’utente che accede possa raggiungere i dati di cui ha bisogno
- Autorizzare con PKCE: invia l’utente attraverso la pagina di consenso nel browser
- Scambiare il codice con un token: scambia il codice di autorizzazione con un access token
- Trovare l’URL della tua API: scopri l’URL di base della tua organizzazione (varia in base alla regione)
- Effettuare la prima chiamata: testa la connessione con una semplice richiesta
Passaggio 1: crea la tua applicazione OAuth
Sezione intitolata “Passaggio 1: crea la tua applicazione OAuth”- Accedi alla Prevu3D Platform.
- Vai su Settings → OAuth.
- Fai clic per creare una nuova applicazione.
- Abilita il flusso Authorization Code.
- Abilita Native Application. L’URI di redirect è fissato a
http://localhost. - Lascia il client secret disattivato. Le app native non ne usano uno.
- Copia e conserva in modo sicuro il tuo Client ID. Ti servirà per ogni autorizzazione.
Passaggio 2: configura l’accesso dell’utente
Sezione intitolata “Passaggio 2: configura l’accesso dell’utente”Il flusso nativo chiama l’API come l’utente che ha effettuato l’accesso, non un utente di servizio. Questo copre i livelli 2 e 3 del modello di sicurezza: quali nodi l’utente può vedere (accesso ai contenuti) e cosa può farci (accesso a ruoli / permessi).
- Assicurati che l’utente che effettuerà l’accesso abbia l’accesso ai contenuti dei nodi (organizzazioni, divisioni, siti, ecc.) richiesti dal tuo caso d’uso.
- Assicurati che l’utente abbia un ruolo su quei nodi con i permessi di cui la tua integrazione ha bisogno (lettura, modifica, gestione, ecc.).
Nella schermata di consenso, l’utente seleziona anche quale organizzazione autorizzare. Gli scope che l’utente approva lì configurano il livello 1.
Passaggio 3: autorizza con PKCE
Sezione intitolata “Passaggio 3: autorizza con PKCE”Le app native non possono conservare un segreto, quindi il flusso usa PKCE per proteggere il codice di autorizzazione. Prima di aprire la pagina di consenso, genera tre valori:
| Valore | Come |
|---|---|
code_verifier | Stringa casuale, da 43 a 128 caratteri |
code_challenge | BASE64URL(SHA256(code_verifier)) senza padding |
state | Stringa casuale; validala quando il redirect ritorna |
Avvia un server loopback locale su una porta libera, quindi apri il browser dell’utente sulla pagina di consenso.
URL di consenso: https://cloud.prevu3d.com/oauth
Parametri di query (tutti obbligatori):
| Parametro | Valore |
|---|---|
response_type | code |
code_challenge_method | S256 |
client_id | Il tuo Client ID |
redirect_uri | Il tuo URI di loopback, ad esempio http://localhost:8765 (includi la porta, nessuna barra finale) |
scopes | Uno per scope, ad esempio scopes=read:basic&scopes=read:hierarchy |
code_challenge | Il challenge PKCE generato sopra |
state | Il tuo valore di stato casuale |
Dopo che l’utente ha effettuato l’accesso e ha fatto clic su Allow, il browser reindirizza al tuo URI di loopback:
http://localhost:8765/?code={authorization_code}&state={state}Se l’utente nega l’accesso, ricevi invece ?error=access_denied. I codici di autorizzazione scadono dopo 60 secondi, quindi scambiali subito.
Passaggio 4: scambia il codice con un access token
Sezione intitolata “Passaggio 4: scambia il codice con un access token”Endpoint: POST https://cloud-api.prevu3d.com/oauth/token
Header: Content-Type: application/x-www-form-urlencoded
Body:
| Campo | Valore |
|---|---|
grant_type | authorization_code |
client_id | Il tuo Client ID |
code | Codice dal redirect |
redirect_uri | Lo stesso URI usato nel Passaggio 3 (inclusa la porta) |
code_verifier | Il verifier PKCE originale |
Non inviare un client secret per le app native.
Esempio di risposta:
{ "hasError": false, "expires_in": 86400, "access_token": "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9...", "refresh_token": "..."}Salva entrambi i token. Usa l’access_token per le chiamate all’API. Quando scade, richiedine uno nuovo con grant_type=refresh_token e il tuo refresh_token salvato (nessun client secret richiesto).
Passaggio 5: ottieni l’URL di base della tua API
Sezione intitolata “Passaggio 5: ottieni l’URL di base della tua API”Chiama l’endpoint di discovery per ottenere l’apiUrl della tua organizzazione. Non codificare staticamente un URL regionale.
Endpoint: GET https://cloud-api.prevu3d.com/oauth/api-info
Header: Authorization: Bearer <your_access_token>
Esempio di risposta:
{ "user": { "..." : "..." }, "organization": { "id": "217ebd23-ec54-4af0-a6d6-4a441a6d1966", "name": "Test Organization" }, "scopes": ["read:basic", "read:hierarchy"], "apiUrl": "https://api-ue1.prevu3d.com/realityconnect-api"}Usa il valore apiUrl come base per tutte le tue chiamate all’API. Annota anche l’organization.id, che ti servirà per molti endpoint.
Passaggio 6: effettua la tua prima chiamata all’API
Sezione intitolata “Passaggio 6: effettua la tua prima chiamata all’API”Ora hai tutto ciò che ti serve: un access token e il tuo URL di base. Facciamo una semplice richiesta per recuperare le divisioni della tua organizzazione:
GET {apiUrl}/v1/nodes/{organization_id}/browseAuthorization: Bearer <your_access_token>Esempio con valori reali:
GET https://api-ue1.prevu3d.com/realityconnect-api/v1/nodes/217ebd23-ec54-4af0-a6d6-4a441a6d1966/browse HTTP/1.1Authorization: Bearer eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9...Una risposta di successo contenente un elenco di divisioni conferma che la tua integrazione funziona correttamente.
Provalo con Python
Sezione intitolata “Provalo con Python”Ecco uno script completo che fa tutto quanto sopra. Sostituisci client_id con il tuo Client ID, quindi eseguilo. Avvia un server loopback temporaneo, apre la pagina di consenso nel tuo browser e stampa le divisioni della tua organizzazione una volta che approvi.
import base64import hashlibimport jsonimport secretsimport webbrowserfrom http.server import BaseHTTPRequestHandler, HTTPServerfrom urllib.parse import parse_qs, quote, urlencode, urlparse
import requests
client_id = "your-client-id"base_url = "https://cloud-api.prevu3d.com"scopes = ["read:basic", "read:hierarchy"]
# Passaggio 1: autorizza con PKCE e ottieni un access tokenverifier = secrets.token_urlsafe(48)[:64]challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest()).decode().rstrip("=")state = secrets.token_urlsafe(32)auth_result = {"code": None, "state": None}
class Handler(BaseHTTPRequestHandler): def log_message(self, *args): pass
def do_GET(self): query = parse_qs(urlparse(self.path).query) auth_result["code"] = query.get("code", [None])[0] auth_result["state"] = query.get("state", [None])[0] self.send_response(200) self.end_headers()
server = HTTPServer(("localhost", 0), Handler)redirect_uri = f"http://localhost:{server.server_address[1]}"consent_params = urlencode( { "response_type": "code", "code_challenge_method": "S256", "client_id": client_id, "redirect_uri": redirect_uri, "code_challenge": challenge, "state": state, })consent_url = f"{base_url.replace('cloud-api.', 'cloud.', 1)}/oauth?{consent_params}"consent_url += "&" + "&".join(f"scopes={quote(scope)}" for scope in scopes)
webbrowser.open(consent_url)server.handle_request()
if auth_result["state"] != state: raise RuntimeError("Invalid state")if not auth_result["code"]: raise RuntimeError("Authorization failed")
token_response = requests.post( f"{base_url}/oauth/token", data={ "grant_type": "authorization_code", "client_id": client_id, "code": auth_result["code"], "redirect_uri": redirect_uri, "code_verifier": verifier, },)token_response.raise_for_status()access_token = token_response.json()["access_token"]
# Passaggio 2: ottieni l'URL della tua API e l'ID dell'organizzazioneapi_info = requests.get( f"{base_url}/oauth/api-info", headers={"Authorization": f"Bearer {access_token}"},).json()
api_url = api_info["apiUrl"]organization_id = api_info["organization"]["id"]
# Passaggio 3: esplora le divisionidivisions = requests.get( f"{api_url}/v1/nodes/{organization_id}/browse", headers={"Authorization": f"Bearer {access_token}"},).json()
print("Divisions:", json.dumps(divisions, indent=2))Risoluzione dei problemi
Sezione intitolata “Risoluzione dei problemi”| Se vedi… | Prova questo… |
|---|---|
| Invalid OAuth grant request dopo aver fatto clic su Allow | Conferma di usare il Client ID di un’app nativa (Authorization Code e Native app abilitati). Un’app con solo Client Credentials non ha un URI di redirect e non può completare questo flusso. |
| Errore della pagina di consenso relativo ai parametri di query | Assicurati che response_type=code, code_challenge_method=S256 e tutti i parametri richiesti siano presenti, inclusi state e scopes. |
| 400 o 403 durante lo scambio del token | Il codice potrebbe essere scaduto (limite di 60 secondi), il redirect_uri potrebbe non corrispondere al Passaggio 3, oppure il verifier e il challenge PKCE potrebbero non corrispondere. |
| 403 Forbidden durante la chiamata all’API | Una richiesta deve superare tutti e tre i livelli di sicurezza. Verifica gli scope OAuth, l’accesso ai contenuti dell’utente che ha effettuato l’accesso e il ruolo dell’utente sul nodo di destinazione. |
| Organizzazione errata nelle risposte dell’API | L’utente seleziona l’organizzazione nella schermata di consenso. Riautorizza e scegli quella corretta. |
Per problemi di connessione, DNS e URL dell’API, consulta Per iniziare.
Cosa c’è dopo?
Sezione intitolata “Cosa c’è dopo?”- Aggiungi la logica per aggiornare il tuo token prima che scada usando
grant_type=refresh_tokencon il tuo refresh token salvato. - Esplora il riferimento API per vedere tutte le operazioni disponibili.