Autenticazione
Un header, in ogni richiesta tranne l'indice autodescrittivo.
Authorization: Bearer <your api key>
I token si creano nella pagina del profilo: fino a
dieci per account, ciascuno revocabile singolarmente, così uno trapelato si può
eliminare senza toccare gli altri. Serve un piano a pagamento: senza, ogni
endpoint tranne / e /v1/account risponde
403 plan_required.
Un'applicazione può anche ottenere un token per te tramite OAuth 2.1: accedi, vedi cosa chiede e fai clic su «Consenti». Il suo token va nello stesso header e funziona allo stesso modo.
Perché non ?key=
Una chiave nella query string finisce in posti dove non l'hai messa tu: i log
di accesso del server web, la cronologia del browser, i log dei proxy e
l'header Referer di qualsiasi cosa a cui la risposta rimandi. Per
questo l'API non la accetta, e risponde 401 missing_key spiegando
il motivo.
I vecchi URL ?export= del sito principale accettano ancora
?key=, perché script scritti anni fa ne dipendono e toglierlo li
romperebbe. È l'unico posto in cui sopravvive: vedi
i vecchi URL di esportazione.
Verificare che una chiave funzioni
/v1/account è la chiamata più economica: non consuma quota e
funziona anche su un account senza piano, quindi risponde sia a «questa chiave
è valida?» sia a «a cosa ho diritto?».
curl -H "Authorization: Bearer $KEY" https://api.publicwww.com/v1/account
{
"plan": "enterprise",
"plan_until": 1819461840,
"full_access": true,
"quota": {
"searches": { "limit": 300, "used": 12, "resets_at": 1787961600 },
"snippets": { "limit": 100, "used": 3, "resets_at": 1787961600 }
},
"limits": {
"disclosed_positions": 4294967295,
"max_per_page": 1000000,
"max_per_page_snippets": 10000
}
}
Cosa può andare storto
| Stato | Codice | Significato |
|---|---|---|
| 401 | missing_key | Manca l'header Authorization: Bearer. Una chiave nella query string non conta. |
| 401 | invalid_key | La chiave non corrisponde a nessun account. Controlla che non ci siano un a capo o una virgoletta di troppo. |
| 403 | plan_required | La chiave è valida; l'account non ha un piano a pagamento. |
Un 401 include anche un header WWW-Authenticate: Bearer,
così i client HTTP che gestiscono l'autenticazione in modo generico si comportano
in modo sensato.
OAuth 2.1 per le applicazioni
Un'applicazione che lavora per conto di altre persone (un assistente,
un'integrazione, un servizio in hosting) non dovrebbe chiedere a ciascuna di
copiare un token. Le manda invece su PublicWWW: accedono, approvano
l'applicazione e questa riceve un token tutto suo. Quel token si invia come
Authorization: Bearer, come qualsiasi altro, e apre l'intera API e
il server MCP su https://api.publicwww.com/mcp,
con il piano, la quota e il limite di frequenza dell'account.
| Cosa | Dove |
|---|---|
| Metadati dell'authorization server (RFC 8414) | https://publicwww.com/.well-known/oauth-authorization-server |
| Metadati della risorsa protetta (RFC 9728) | https://api.publicwww.com/.well-known/oauth-protected-resource |
| Endpoint di autorizzazione | https://publicwww.com/oauth/authorize |
| Endpoint del token | https://publicwww.com/oauth/token |
| Endpoint di revoca (RFC 7009) | https://publicwww.com/oauth/revoke |
Identificare l'applicazione
Non c'è registrazione dei client. Il client_id è l'URL https di un
piccolo documento JSON pubblicato dall'applicazione: un documento di metadati
del client. PublicWWW lo legge ogni volta che qualcuno si collega, quindi il nome
e gli indirizzi di ritorno sono sempre aggiornati, e chi approva vede quale host
li ha pubblicati.
{
"client_id": "https://app.example.com/oauth/client.json",
"client_name": "Example App",
"redirect_uris": ["https://app.example.com/oauth/callback"],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}
-
Il
client_idall'interno del documento deve essere esattamente l'URL da cui il documento viene servito. Il documento viene scaricato via https, da un URL con un percorso, senza seguire redirect; deve rispondere entro 5 secondi e restare sotto i 64 KB. -
I
redirect_urissono indirizzi https, oppure http su127.0.0.1,localhosto[::1]per un'applicazione che gira sul computer della persona stessa: in quel caso va bene qualsiasi porta. Gli schemi personalizzati comemyapp://non sono accettati. -
Ogni applicazione è un client pubblico: la richiesta del token non contiene
alcun segreto, qualunque
token_endpoint_auth_methodindichi il documento. Il codice di autorizzazione è invece protetto da PKCE.
Il flusso
Authorization code con PKCE; S256 è l'unico metodo. Manda la
persona all'endpoint di autorizzazione:
https://publicwww.com/oauth/authorize
?response_type=code
&client_id=https%3A%2F%2Fapp.example.com%2Foauth%2Fclient.json
&redirect_uri=https%3A%2F%2Fapp.example.com%2Foauth%2Fcallback
&code_challenge=<BASE64URL(SHA-256(code_verifier))>
&code_challenge_method=S256
&state=<random>
Se non l'ha già fatto, la persona accede con un codice monouso ricevuto via
email, vede il nome dell'applicazione, l'host del suo documento e dove verrà
riportata, e fa clic su «Consenti» o «Annulla». Su redirect_uri
tornano code, il tuo state e
iss=https://publicwww.com (RFC 9207). Un codice è valido per dieci
minuti e funziona una sola volta. Scambialo:
curl https://publicwww.com/oauth/token \
-d grant_type=authorization_code \
-d code="$CODE" \
-d code_verifier="$VERIFIER" \
-d client_id=https://app.example.com/oauth/client.json \
-d redirect_uri=https://app.example.com/oauth/callback
{ "access_token": "<token>", "token_type": "Bearer", "scope": "mcp" }
scope si può omettere: c'è un solo scope, mcp, e copre
l'intera API. Anche resource (RFC 8707) si può omettere; se viene
inviato, vale https://api.publicwww.com/mcp oppure
https://api.publicwww.com.
Quanto dura un token
Finché non viene revocato: non c'è scadenza né refresh token. Un'integrazione che funziona oggi continua a funzionare domani senza che nessuno debba toccarla. Un token viene revocato solo intenzionalmente: la persona scollega l'applicazione nella sua pagina del profilo, l'applicazione stessa lo revoca, oppure l'account viene eliminato.
curl https://publicwww.com/oauth/revoke \
-d token="$TOKEN" \
-d client_id=https://app.example.com/oauth/client.json
L'endpoint di revoca risponde sempre 200, che il token esistesse o
no.
Errori OAuth
| Dove | Codice | Significato |
|---|---|---|
| Autorizzazione | pagina di errore | Il documento del client_id non è leggibile, oppure redirect_uri non vi è elencato. La persona non viene rimandata indietro: un indirizzo non verificato non viene mai seguito. |
| Autorizzazione | invalid_request | Manca code_challenge, oppure il metodo non è S256. |
| Autorizzazione | unsupported_response_type | Qualsiasi valore diverso da response_type=code. |
| Autorizzazione, token | invalid_target | Una resource diversa dall'API. |
| Autorizzazione | access_denied | La persona ha fatto clic su «Annulla». |
| Token | invalid_grant | Il codice è sconosciuto, già usato, scaduto o emesso per un altro client_id; oppure code_verifier o redirect_uri non corrispondono. |
| Token | unsupported_grant_type | Qualsiasi valore diverso da authorization_code. |
Gli errori di autorizzazione, tranne la pagina di errore, tornano a
redirect_uri come error, error_description,
state e iss; gli errori del token sono un
400 con gli stessi due campi in JSON.