Dónde colocar una clave API: un encabezado HTTP personalizado VS el encabezado de autorización con un esquema personalizado

17

Estoy diseñando una API REST usando autorización / autenticación a través de una clave API.

Traté de averiguar cuál es el mejor lugar y descubrí que muchas personas sugieren usar un encabezado HTTP personalizado como ProjectName-Api-Key, por ejemplo:

ProjectName-Api-Key: abcde

pero también es posible e ideológicamente correcto usar el Authorizationencabezado con un esquema personalizado, por ejemplo:

Authorization: ApiKey abcde

Por otro lado, encontré la consideración de que un esquema de Autorización personalizado puede ser inesperado y no admitido por algunos clientes y de todos modos conduce a un código personalizado, por lo que es mejor usar un encabezado personalizado ya que los clientes no tienen expectativas al respecto.

¿De qué manera preferirías enviar una clave API?

RomanG
fuente
Los proyectos bajo mi guía usan Authorization: Bearer <token>encabezado y nunca hubo un solo problema con eso. Los tokens son JWT s.
Andy
1
@DavidPacker Según tengo entendido, el Beareresquema se usa exclusivamente con oAuth2. Aplicarlo por separado de oAuth suena como un mal uso. ¿Por qué es correcto usar este esquema si no hay oAuth? Por cierto, tuve problemas para elegir un tipo de autorización para mi API. La API estará disponible solo para un servicio confiable, por lo que investigué el flujo de credenciales del cliente de oAuth2 y no he encontrado ningún beneficio en comparación con ApiKey en mi caso.
RomanG
@DavidPacker Entonces entendí que la autorización ApiKey podría considerarse como una implementación válida de oAuth si ApiKeyse renombraba e interpretaba como Access Tokenotorgada al cliente sin un tiempo de vencimiento. Es un tipo de aspecto filosófico, decidí no aportar definiciones complejas si mi caso puede describirse en términos simples y decidí llamarlo simplemente "ApiKey". Si su protocolo implementa el estándar oAuth, puedo aceptar usarlo Bearer, pero no lo hace, supongo que este esquema no puede aplicarse.
RomanG
2
Te estás limitando demasiado. Al consumidor de API no podría importarle menos si ha implementado OAuth o no. Lo que les importa es la seguridad del token, que la emisión del token funciona y que pueden autenticarse adecuadamente. Recomiendan usar Bearer directamente en la documentación de JWT . JWT se ajusta perfectamente al esquema de portador y no podría recomendar más JWT. Son perfectos para aplicaciones REST porque puede autenticar a un usuario incluso sin tocar la base de datos, a menos que necesite la función de revocación de token.
Andy
1
(pase por) ... tenga cuidado de saber que las claves de API son secretos compartidos que generalmente se comparten entre una parte confiable configurada y un autenticador, no para comunicar identidad o autorización. Dicho de otra manera, solo están destinados a iniciar un protocolo de enlace de seguridad, no representan un resultado de autenticación. La clave API comunica su autoridad para identificarse contra el autenticador de confianza del sistema. Usar la clave como un token para controlar el acceso seguro a los recursos es malo juju
K. Alan Bates

Respuestas:

12

Si usa Autorización, sea consistente

Algunos argumentarán que lo siguiente es innecesario ( y no hace mucho tiempo hubiera estado de acuerdo con ellos ) pero, en estos días, si usamos el Authorizationencabezado, deberíamos informar el tipo de token, porque las claves API no son autodescriptivas per se 1 .

¿Por qué creo que es necesario y por qué creo que es importante? Porque hoy en día el soporte de diferentes protocolos de autenticación / autorización se ha convertido en algo imprescindible. Si planeamos usar el Authorizationencabezado para todos estos protocolos, tenemos que hacer que nuestro servicio de autenticación sea consistente. La forma de comunicar qué tipo de token enviamos y qué protocolo de autorización se debe aplicar también debe ir en el encabezado.

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

No me importaba esto, pero después de trabajar con aplicaciones cliente de aplicaciones cuyas actualizaciones no estaban garantizadas (móviles y sensores en su mayoría), comencé a hacerlo. Comencé a ser más cauteloso en la forma en que implemento la seguridad para poder expandirla sin molestar a los clientes y sin demasiado dolor en el lado del servidor.

Preocupaciones

Los problemas que enfrenté al implementar mis propios esquemas han sido similares a los comentados.

Por otro lado, encontré la consideración de que un esquema de Autorización personalizado puede ser inesperado y no admitido por algunos clientes y de todos modos conduce a un código personalizado

Diga clientes , diga bibliotecas, marcos, servidores proxy inversos .

Ventajas

Una ventaja importante es el caché. Las cachés compartidas no almacenarán en caché el encabezado (y eso es bueno, por supuesto) a menos que usted indique lo contrario.

Entonces, ¿autorización o encabezado personalizado?

Según mi experiencia, implementar mi propio Authorizationesquema me ha llevado la misma cantidad de trabajo (o más) que implementar encabezados de autorización personalizados, con la ligera diferencia de tener más libertad de diseño y más control sobre el caché cuando he usado encabezados personalizados. La razón es bastante estúpida, la mayoría de las veces tengo Cache-controlconfigurada no-cacheo no-store, lo que me permite hacer que las llamadas al servidor sean más deterministas (esto es importante cuando se trata de rastrear y probar) independientemente de la topología de la red.


1: Creo que esta respuesta es muy clara con respecto a las claves API

Laiv
fuente
44
El uso de X-está en desuso a partir de 2012: stackoverflow.com/a/3561399/923720
Darkhogg
1
ops! No lo sabia Editado y arreglado.
Laiv
Antes de esta pregunta, pensé que casi todo el mundo ponía la clave API en la URL, pero usé HTTPS para ocultarla. Es bueno ver algunas alternativas. Por ejemplo, Contentful permite Autorización o pamameter consulta: contentful.com/developers/docs/references/content-delivery-api/...
user949300
1
@ user949300 ... el uso de un secreto compartido cifrado (p. ej., clave de API en uri sobre ssl) es obviamente más seguro que nada, pero es fácilmente suplantable si se intercepta y no proporciona granularidad sobre las identidades. Nunca he usado api_keys para otra cosa que no sea comunicación de máquina a máquina, donde estoy haciendo coincidir el secreto compartido entre las partes que confían y las identidades de la máquina en la lista blanca autorizadas para actuar con ese secreto compartido. Después de realizar la conexión de máquina a máquina, el operador humano se autentica utilizando otros medios.
K. Alan Bates
@K. Alan Bates La mayoría de mis interacciones API han sido para cosas relativamente "sin importancia", como niveles libres de geocodificación, informes meteorológicos y similares, donde la clave API es más para limitar la velocidad que los secretos de usuario serios. Entonces, en cuanto a OP, depende del nivel de seguridad que se necesita.
user949300