Dove posizionare una chiave API: un'intestazione HTTP personalizzata VS l'intestazione di autorizzazione con uno schema personalizzato


17

Sto progettando un'API REST utilizzando l'autorizzazione / autenticazione tramite una chiave API.

Ho cercato di capire qual è il posto migliore per questo e ho scoperto che molte persone suggeriscono di utilizzare un'intestazione HTTP personalizzata come ProjectName-Api-Key, ad esempio:

ProjectName-Api-Key: abcde

ma è anche possibile e ideologicamente corretto utilizzare l' Authorizationintestazione con uno schema personalizzato, ad esempio:

Authorization: ApiKey abcde

D'altra parte, ho scoperto che uno schema di autorizzazione personalizzato può essere inaspettato e non supportato da alcuni client e porta comunque a un codice personalizzato, quindi è meglio usare un'intestazione personalizzata poiché i clienti non hanno aspettative al riguardo.

In che modo preferiresti inviare una chiave API?


I progetti sotto la mia guida usano l' Authorization: Bearer <token>intestazione e non c'è mai stato un singolo problema. I token sono JWT .
Andy,

1
@DavidPacker A quanto ho capito, lo Bearerschema viene utilizzato esclusivamente con oAuth2. Applicarlo separatamente da oAuth sembra un uso improprio. Perché è corretto utilizzare questo schema se non c'è oAuth? A proposito, ho avuto problemi con la scelta di un tipo di autorizzazione per la mia API. L'API sarà disponibile solo per un servizio fidato, quindi ho studiato il flusso di credenziali del client di oAuth2 e nel mio caso non ho trovato alcun vantaggio rispetto ad ApiKey.
RomanG,

@DavidPacker Poi ho capito che l'autorizzazione ApiKey poteva essere considerata un'implementazione oAuth valida se ApiKeyfosse stata rinominata e interpretata come Access Tokenconcessa al client senza un tempo di scadenza. È una specie di aspetto filosofico, ho deciso di non portare definizioni complesse se il mio caso può essere descritto in termini semplici e ho deciso di chiamarlo semplicemente "ApiKey". Se il tuo protocollo implementa oAuth standart, posso essere d'accordo sull'uso Bearer, ma non lo è, immagino che questo schema non possa essere applicato.
RomanG,

2
Ti stai limitando troppo. Al consumatore API non potrebbe importare di meno se hai implementato OAuth o meno. Ciò a cui tengono è la sicurezza dei token, che l'emissione di token funziona e che possono essere correttamente autenticati. Raccomandano di usare Bearer direttamente nella documentazione JWT . JWT si adatta perfettamente allo schema Bearer e non potrei raccomandare di più JWT. Sono perfetti per le applicazioni REST perché è possibile autenticare un utente anche senza colpire il database, a meno che non sia necessaria la funzionalità di revoca del token.
Andy,

1
(guida da) ... fai attenzione a sapere che le chiavi API sono segreti condivisi in genere condivisi tra una parte affidataria configurata e un autenticatore, per non comunicare identità o autorizzazione. Detto in altro modo, intendono solo avviare una stretta di mano di sicurezza, non rappresentare un risultato di autenticazione. La chiave API comunica la tua autorità per identificarti rispetto all'autenticatore di fiducia del sistema. Usare la chiave come token per controllare l'accesso sicuro alle risorse è un male juju
K. Alan Bates,

Risposte:


12

Se usi l'autorizzazione, sii coerente

Alcuni sosterranno che non è necessario quanto segue ( e non molto tempo fa avrei concordato con loro ) ma, in questi giorni, se utilizziamo l' Authorizationintestazione dovremmo informare il tipo di token, perché le chiavi API non sono auto-descrittive di per sé 1 .

Perché penso sia necessario e perché penso sia importante? Perché oggigiorno supportare diversi protocolli di autenticazione / autorizzazione è diventato un must. Se intendiamo utilizzare l' Authorizationintestazione per tutti questi protocolli, dobbiamo rendere coerente il nostro servizio di autenticazione. Il modo di comunicare quale tipo di token inviamo e quale protocollo di autorizzazione dovrebbe essere applicato dovrebbe essere presente anche nell'intestazione.

Authorization: Basic xxxx
Authorization: Digest xxxx
Authorization: Bearer xxxx
Authorization: ApiKey-v1 xxxx
Authorization: ApiKey-v2 xxxx

Non mi importava questo, ma dopo aver lavorato con le app client i cui aggiornamenti non erano garantiti (principalmente cellulari e sensori), ho iniziato a farlo. Ho iniziato a essere più cauto nel modo in cui implemento la sicurezza in modo da poterlo espandere senza fare confusione con i client e senza troppa sofferenza sul lato server.

preoccupazioni

I problemi che ho riscontrato nell'attuazione dei miei schemi sono stati simili a quelli commentati.

D'altra parte, ho scoperto che uno schema di autorizzazione personalizzato può essere inatteso e non supportato da alcuni client e porta comunque a un codice personalizzato

client , dì librerie, framework, proxy inversi .

vantaggi

Un vantaggio importante è la cache. Le cache condivise non memorizzeranno nella cache l'intestazione (e questo ovviamente va bene) a meno che tu non dica diversamente.

Quindi autorizzazione o intestazione personalizzata?

Per la mia esperienza, l'implementazione del mio Authorizationschema mi ha richiesto la stessa quantità di lavoro (o più) rispetto all'implementazione delle intestazioni di autorizzazione personalizzate, con la leggera differenza di avere più libertà di progettazione e maggiore controllo sulla cache quando ho usato le intestazioni personalizzate. Il motivo è piuttosto stupido, il più delle volte ho Cache-controlimpostato no-cacheo no-store, permettendomi di rendere più deterministiche le chiamate al server (questo è importante quando si tratta di tracciamento e test) indipendentemente dalla topologia della rete.


1: Trovo che questa risposta sia molto chiara riguardo alle chiavi API


4
L'utilizzo di X-è deprecato a partire dal 2012: stackoverflow.com/a/3561399/923720
Darkhogg

1
ops! Non lo sapevo. Modificato e risolto.
Laiv,

Prima di questa domanda pensavo che quasi tutti inserissero la chiave API nell'URL, ma ho usato HTTPS per nasconderla. Bello vedere alcune alternative. Ad esempio, Contentful consente l'autorizzazione o interroga pamameter: contentful.com/developers/docs/references/content-delivery-api/…
user949300

1
@ user949300 ... l'utilizzo di un segreto condiviso crittografato (ad es. chiave API in uri over ssl) è ovviamente più sicuro di niente, ma è facilmente falsificabile se intercettato e non fornisce granularità rispetto alle identità. Non ho mai usato api_keys per qualcosa di diverso dalla comunicazione machine to machine in cui sto abbinando il segreto condiviso tra le parti fiducianti e le identità della macchina nella whitelist autorizzate ad agire con quel segreto condiviso. Dopo aver effettuato il collegamento macchina-macchina, l'operatore umano esegue l'autenticazione con altri mezzi.
K. Alan Bates,

@K. Alan Bates La maggior parte delle mie interazioni API sono state per cose relativamente "non importanti" come livelli gratuiti di geocodifica, bollettini meteorologici e simili, in cui la chiave API è più per la limitazione della velocità che per i segreti degli utenti seri. Quindi, come per l'OP, dipende dal livello di sicurezza necessario.
user949300,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.