¿Cómo manejar los URI que contienen parámetros no utilizados por la API?

7

En una interfaz de API REST, ¿debería verificar explícitamente que el cliente usó solo los parámetros utilizados por la API y devolver un HTTP 403 si un parámetro del que la API no se había incluido estaba incluido en la solicitud?

Un poco de contexto. Estoy trabajando en una API que minimiza los archivos JavaScript y MENOS. Originalmente, los archivos JavaScript se reducían utilizando el compilador de cierre de Google. Dado que Closure Compiler tiene múltiples niveles de optimización (solo espacios en blanco, optimizaciones simples y optimizaciones avanzadas), la API también hizo posible que la persona que llama especifique (opcionalmente) el nivel, por lo que:

POST http://example.com/api/v1/js?level=whitespace

y:

POST http://example.com/api/v1/js?level=advanced

en la mayoría de los casos daría resultados diferentes.

Recientemente, tuve que agregar soporte para ES6. Dada la falta de soporte adecuado para ES6 por Closure Compiler, agregué YUI Compressor. Como este no tiene niveles de optimización, la llamada es ahora simplemente:

POST http://example.com/api/v1/es6

Siguiendo a POLA , tengo la impresión de que no puedo dejar que las personas que llaman usen la API de esta manera:

POST http://example.com/api/v1/es6?level=advanced

porque esperarían un resultado específico, pero obtendrían uno diferente. La solución sería verificar la presencia del parámetro level en el URI y devolver un mensaje de error que indique que el parámetro no es compatible.

Pero compruebo este parámetro específico, ¿por qué no verifico lecel (un error tipográfico), o optimize (una conjetura), o cualquier otra cosa?

Por lo tanto, ¿la API espera que los parámetros a , b y c se incluyan posiblemente en el URI, cuál debería ser la respuesta si el URI también contiene d o e ?

    
pregunta Arseni Mourzenko 29.12.2017 - 16:39

4 respuestas

2

Yo diría que su enfoque actual es el que sigue el principio de menos asombro.

Hablando de forma resumida, definió dos recursos diferentes en v1: js y es6. No hay ninguna razón por la que estos deban aceptar los mismos parámetros de consulta, lo que ayuda en la representación del recurso.

Y, sin embargo, estás pensando que debido a que todos estos son minimizadores de js, aceptarían los mismos parámetros. Y en realidad no es una sorpresa que diferentes minimizadores requieran diferentes parámetros.

Otra idea es que los consumidores de API están muy acostumbrados a diferentes rutas que requieren diferentes parámetros, por lo general no tienen la transparencia de cambiar los recursos y mantener los mismos parámetros. La excepción a esta regla puede ser un parámetro de autenticación o un parámetro de paginación para la mayoría de las API, pero esta es una excepción porque se ocupa de preocupaciones transversales que son responsabilidades de toda la aplicación.

En su caso, ninguno de estos se aplica directamente. Creo que su diseño actual es el que se siente más natural y asombra menos.

    
respondido por el Alpha 04.01.2018 - 12:41
3

Como ya tiene una versión para la API (lo que significa que no hay problemas de compatibilidad con versiones anteriores), sería más lógico validar la entrada y, en parámetros inesperados, dar 400 (solicitud incorrecta, muy genérico), 422 ( Entidad no procesable), que algunos argumentan es mejor que 400 , ver más abajo. Menos aplicables son 404 (No encontrado), porque se encuentra es6 , o en casos muy raros, incluso 501 (No implementado).

El uso del código HTTP 4xx ahorrará tiempo a los usuarios para solucionar problemas de acceso a la API.

Consulte también here ( 422 sugerido también) o aquí , lo que explica por qué 422 puede ser más apropiado. Consulte también esta pregunta .

Personalmente, me quedé con 400 como código HTTP bien entendido y de amplio espectro.

Según el caso de uso, algunos parámetros de cadena de consulta pueden ser ignitables, por ejemplo, con prefijo de subrayado, para los casos en que la única forma de evitar el almacenamiento en caché es cambiar la URL para incluir "huellas digitales".

    
respondido por el Roman Susi 29.12.2017 - 17:34
1

level = ... parece ser un problema de compatibilidad hacia atrás. Para no frustrar a los usuarios actuales, verificaría el nivel, ya que en realidad hizo algo en la versión anterior, pero no hace nada en la versión actual y da un mensaje de advertencia ("el nivel está obsoleto y actualmente no hace nada"), pero No se detiene el procesamiento. Daría el error como parte de la respuesta JSON en lugar del error http. Generalmente los reservo para errores que impidan el procesamiento.

Si lo que está respaldando tiene el potencial de liberar la fecha personal (atención médica o crédito), entonces en el caso de variables adicionales o mal escritas, simplemente no devolvería nada. Si son lo suficientemente persistentes, entonces lo resolverán.

Si no hay posibilidad de que la información confidencial se filtre, brinde el error o la advertencia que desee. En este caso, pondría los mensajes de advertencia en la respuesta JSON, ya que no afectaría el procesamiento.

En cualquiera de los casos, debe verificar todas las variables y valores que se están pasando para confirmar que no hay inyecciones de scripts o sql entre sitios o cualquier otro problema de seguridad.

    
respondido por el Robert Baron 29.12.2017 - 17:57
1

Si está dispuesto a gastar el tiempo y el esfuerzo para validar en comparación con los parámetros no utilizados, sugiero que la validación sea opcional.

Por ejemplo, podría aceptar un indicador strict=true (como parámetro o encabezado de solicitud) que generaría un error si el cliente envía un parámetro desconocido (o no utilizado). Aquellos que prefieren las redes de seguridad basadas en herramientas (por ejemplo, aquellos que prefieren un compilador) probablemente lo usarán todo el tiempo, mientras que aquellos que tienen una preferencia diferente pueden elegir limitar su uso a las fases de desarrollo y / o prueba.

Algunos marcos web (por ejemplo, Rails ) ignoran los parámetros desconocidos de forma predeterminada. Esto puede ayudar con la compatibilidad hacia adelante ya que sus clientes pueden comenzar a solicitar una característica incluso antes de que su servidor la admita. Por ejemplo, puede elegir habilitar el soporte para el parámetro level más adelante y no será necesario cambiar los clientes.

    
respondido por el Hosam Aly 01.01.2018 - 19:52

Lea otras preguntas en las etiquetas