Gestire i client OAuth2
Client OAuth2
Creare e gestire client OAuth2 per l'accesso alle API. Ogni client riceve ambiti (autorizzazioni) individuali e può generare token con validità di 1 ora.
POST /oauth/token
grant_type=client_credentials
Flusso delle credenziali del client
Il flusso OAuth2 Client Credentials Grant (RFC 6749, sezione 4.4) per l’autenticazione da macchina a macchina
Creare un client
Nel backend, in Strumenti → Client OAuth2 di xoPort, creare un nuovo client con gli ambiti desiderati.
Richiedere il token
Richiedere un token di accesso dall'endpoint /oauth/token utilizzando l'ID client e il segreto.
Utilizzare l'API
Utilizzare il token nell'intestazione Authorization: Bearer per tutte le richieste API.
Richiedere il token
curl -X POST https://shop.de/xpanel/xoport/oauth/token
-H "Content-Type: application/x-www-form-urlencoded"
-d "grant_type=client_credentials"
-d "client_id=xoc_abc123..."
-d "client_secret=xos_def456..."
Risposta
{
"access_token": "xoat_eyJhbGciOiJIUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "products:read products:write categories:read"
}
Errore all'endpoint del token
L'endpoint del token risponde nel formato OAuth2 con error e error_description, verificati in questo ordine:
| HTTP | error |
Quando |
|---|---|---|
| 405 | invalid_request |
Richiesta non effettuata tramite POST |
| 400 | unsupported_grant_type |
grant_type non è client_credentials, anche in caso di JSON troncato che non è leggibile |
| 400 | invalid_request |
client_id o manca client_secret; a partire dalla v2.122.11 anche uno di questi come elenco (client_id[]=…, nel corpo JSON un array) |
| 429 | rate_limit_exceeded |
più di 30 richieste in 300 secondi per questo client_id (vedi «Limite di richieste» più sotto) |
| 401 | invalid_client |
Client sconosciuto, secret errato o client disattivato |
| 400 | invalid_scope |
Nessuno degli scope richiesti è consentito al client. A partire dalla v2.122.11, vale anche per uno scope richiesto che non può essere letto (UTF-8 non valido o un elenco come scope[]=…); non viene emesso alcun token. |
In assenza di scope, sono validi tutti gli ambiti del client.
Scope disponibili
| Ambito | Descrizione | Operazioni |
|---|---|---|
products:read |
Leggi prodotti | GET |
products:write |
Crea/aggiorna prodotti | POST |
products:delete |
Elimina prodotti | DELETE |
categorie:leggere |
Leggi categorie | GET |
categorie:scrittura |
Crea/aggiorna categorie | POST |
categories:delete |
Elimina categorie | DELETE |
clienti:leggere |
Leggi clienti | GET |
customers:write |
Crea/aggiorna clienti | POST |
customers:delete |
Elimina clienti | DELETE |
manufacturers:read |
Leggi produttori | GET |
manufacturers:write |
Crea/aggiorna produttori | POST |
manufacturers:delete |
Elimina produttori | DELETE |
ordini:leggere |
Leggi ordini | GET |
news:read |
Leggi gli articoli delle notizie | GET |
news:write |
Crea/aggiorna un articolo di notizie | POST |
news:delete |
Elimina articolo di notizie | DELETE |
newscategories:read |
Leggi le categorie delle notizie | GET |
newscategories:write |
Crea/aggiorna categorie di notizie | POST |
newscategories:delete |
Elimina categorie di notizie | DELETE |
faq:read |
Leggi le FAQ | GET |
faq:write |
Crea/aggiorna le FAQ | POST |
faq:delete |
Elimina FAQ | DELETE |
faqcategories:read |
Leggi le categorie delle FAQ | GET |
faqcategories:write |
Crea/aggiorna categorie FAQ | POST |
faqcategories:delete |
Elimina categorie FAQ | DELETE |
Introspezione degli scope
Con l’endpoint /me è possibile interrogare gli scope del token corrente:
curl -X GET https://shop.de/xpanel/xoPort/me
-H "Authorization: Bearer xoat_eyJhbGciOi..."
Risposta
{
"success": true,
"api_version": "2.122.11",
"type": "client_info",
"data": {
"client_id": "xoc_abc123...",
"client_name": "Mein API Client",
"scopes": ["products:read", "products:write", "categories:read"],
"rate_limit": 5000,
"rate_limit_window": 3600,
"rate_limit_remaining": 4987,
"rate_limit_reset": 1792327500,
"token_expires_at": "2026-10-18 15:00:00",
"token_created_at": "2026-10-18 14:00:00",
"client_created_at": "2026-01-15 10:30:00",
"client_last_used_at": "2026-10-18 14:22:15"
},
"timestamp": "2026-10-18 14:22:16"
}
A partire dalla versione v2.122.11 rate_limit_window, la durata della finestra di conteggio è espressa in secondi (sempre 3600). rate_limit_remaining e rate_limit_reset hanno gli stessi valori delle intestazioni X-RateLimit-Remaining e X-RateLimit-Reset della stessa risposta; la richiesta a /me viene conteggiata. Per i client senza limite di richieste, entrambi i valori sono null.
Limite di richieste
Il limite di richieste si applica per client, non per token: tutti i token e i processi di un client condividono un unico contatore. Il conteggio avviene in una finestra mobile di 3600 secondi; un posto si libera non appena la richiesta più vecchia conteggiata risale a più di un'ora fa. Il valore (rate_limit, richieste per finestra) va impostato nel backend del client; GET /me lo mostra (null significa illimitato, 0 ha lo stesso effetto).
Impostazioni predefinite (a partire dalla versione 4.9.17; in precedenza, un campo vuoto indicava "illimitato"): per l’amministratore, il campo è preimpostato a 5000 al momento della creazione; non è possibile impostare un valore superiore e, se salvato vuoto, viene considerato pari a 5000. Un valore superiore a 5000 impostato da XONIC rimane valido fintanto che il campo non viene modificato. A partire dalla versione 4.9.174 di Shop, la funzione «Modifica client» mostra, per un client illimitato, un campo vuoto con l’indicazione «Illimitato (impostato da XONIC)»; se salvato vuoto, rimane illimitato; un numero fino a 5000 lo limita, mentre solo XONIC può riportarlo a illimitato. ⚠️ Fino alla versione 4.9.173 di Shop, a un cliente illimitato veniva assegnato il valore 5000 non appena l’amministratore lo salvava, anche se venivano modificati solo il nome o la nota. Nell’amministratore XONIC il campo è vuoto, e «vuoto» in quel contesto significa «illimitato». ⚠️ Fino alla versione Shop 4.9.173, durante la creazione con il campo vuoto veniva comunque generato un client con valore 5000 se la colonna nel database aveva il valore predefinito 5000 (ad esempio dopo una reinstallazione a partire dalla versione Shop 4.9.17). Verificate questi valori dopo la creazione in GET /me → rate_limit. Nelle versioni di Shop dalla 4.9.17 alla 4.9.167, ogni controllo HealthCheck e ogni aggiornamento reimpostano un client illimitato a 5000; a partire dalla versione 4.9.168, il valore “illimitato” rimane invariato. Una modifica del limite ha effetto immediato, anche per i token attivi.
Quota in ogni risposta A partire dalla v2.122.11
Ogni risposta a una richiesta con un token valido proveniente da un client con limite di richieste contiene tre intestazioni:
| Intestazione | Contenuto |
|---|---|
X-RateLimit-Limit |
Limite di richieste del cliente ogni 3600 secondi |
X-RateLimit-Remaining |
Richieste ancora disponibili nella finestra; questa richiesta è già stata conteggiata. " 0 " significa: questa richiesta è stata ancora accettata, la prossima verrà respinta. |
X-RateLimit-Reset |
Tempo Unix (secondi dal 1970, UTC) in cui la richiesta più vecchia conteggiata esce dalla finestra: il suo momento più 3600 secondi, senza cambio d’ora |
- Con intestazioni: dati, risposte di errore come 400, 403 o 404, download di file, richieste XML con token e la risposta 429 stessa.
- Senza intestazioni: client senza limite di richieste, richieste senza token valido (401), richieste XML senza token o provenienti da un indirizzo con autorizzazione IP dell’interfaccia XML e dell’endpoint del token.
- Il resto vale per tutti i processi del client nel loro insieme: ciò che viene indicato come risposta potrebbe essere già stato utilizzato da un processo parallelo.
- I negozi fino alla versione 4.9.170 non inviano queste intestazioni. La loro assenza non significa «illimitato»: in tal caso, consultare
GET /me.
Se il limite viene superato, l’API risponde con HTTP 429 e Retry-After; si veda l’esempio nella sezione Gestione degli errori.
Limite proprio sull’endpoint del token
POST /oauth/token ha un proprio limite: 30 richieste in 300 secondi per client_id, anch’esso mobile; vengono conteggiate anche le richieste con secret errato. In tal caso viene restituito un codice di stato HTTP 429 con rate_limit_exceeded. A partire dalla versione v2.122.11, Retry-After indica i secondi che mancano alla prossima accettazione (da 1 a 300); in precedenza il valore era fisso a 300. L’endpoint del token non invia X-RateLimit-*. Un token è valido per un’ora: recuperatelo una sola volta e trasmettetelo a tutti i processi.
Log di utilizzo
Nel backend, il log di utilizzo mostra per ogni client le ultime 1000 richieste con richiesta e risposta. Non sono inclusi gli interruzioni dell’esportazione con codice HTTP 400 prima dell’esecuzione di una query (errori di filtro, di scorrimento e di percorso), i documenti giustificativi e i singoli allegati dei ticket, la risposta 429 e le richieste XML. Tuttavia, queste richieste vengono comunque conteggiate ai fini del limite di richieste, ad eccezione del codice di risposta 429 e delle richieste XML senza token.
Limitazione IP (opzionale)
A partire dalla v2.119.0, l’API REST richiede sempre un token OAuth2 e si applicano i relativi ambiti (scopes). L’autorizzazione IP dell’interfaccia XML (XML_PORT_IP_FILTER) non dà diritto all’accesso all’API REST.
Inoltre, è possibile limitare l’accesso a indirizzi fissi. Se il campo XOPORT_REST_IP_LIST è compilato, una richiesta deve provenire da un indirizzo presente nell’elenco e contenere un token valido; l’elenco non sostituisce mai il token. Le richieste provenienti da altri indirizzi ricevono il messaggio di errore 403 con reason: deny_ip_not_listed.
Avviso di sicurezza
Non memorizzare mai il client secret e l’access token nel codice frontend o in repository pubblici!