servicio desde consumir consume con javascript api rest

javascript - desde - Dogfooding nuestra propia API de tarifa limitada



javascript consume rest web service (9)

Visión general:

Mi empresa ha desarrollado una API de tarifa limitada. Nuestro objetivo es doble:

  • R: Cree un ecosistema de desarrolladores sólido alrededor de nuestro producto.
  • B: demuestre el poder de nuestra API usándola para impulsar nuestra propia aplicación.

Aclaración: ¿Por qué limitar la tasa?

Calificamos el límite de nuestra API, porque la vendemos como una adición a nuestro producto. El acceso anónimo a nuestra API tiene un umbral muy bajo para llamadas API por hora, mientras que a nuestros clientes pagos se les permite más de 1000 llamadas por hora o más.

El problema:

Nuestra API de tarifa limitada es excelente para el ecosistema de desarrolladores, pero para que podamos alimentarla no podemos permitir que se limite a la misma limitación de velocidad. El front-end de nuestra API es todo JavaScript, que realiza llamadas directas de Ajax a la API.

Entonces la pregunta es:

¿Cómo se asegura una API para que la limitación de velocidad se pueda eliminar cuando en el proceso de eliminación de dicha limitación de velocidad no se pueda suplantar fácilmente?

Soluciones exploradas (y por qué no funcionaron)

  1. Verifique el referente contra el encabezado del host. - Defectuoso porque el referente es fácilmente falsificado.

  2. Use un HMAC para crear una firma basada en la solicitud y un secreto compartido, luego verifique la solicitud en el servidor. - Defectuoso porque el secreto y el algoritmo se determinarían fácilmente al mirar el JavaScript frontal.

  3. Proxy la solicitud y firme la solicitud en el proxy: aún tiene fallas, ya que el proxy expone la API.

La pregunta:

Estoy mirando a las mentes brillantes en Stack Overflow para presentar soluciones alternativas. Como resolverías este problema?


¿Puede soportar una instancia separada de la interfaz de usuario y la API sin acelerador, y luego restringir el acceso a las direcciones IP que provienen de su organización?

Por ejemplo, implemente todo detrás de su firewall corporativo y conecte la aplicación a la misma base de datos que la instancia pública si necesita compartir datos entre instancias.


Compra tu producto. Conviértete en un cliente pagado de ti mismo.

"El acceso anónimo a nuestra API tiene un umbral muy bajo para llamadas API por hora, mientras que a nuestros clientes pagos se les permite más de 1000 llamadas por hora o más".

Esto también ayuda a probar el sistema desde la perspectiva del cliente.


Configure varias cuentas y elija una de ellas al azar en cada solicitud, o cambie la que usa cada hora más o menos. De esta forma, puede distribuir la carga en n cuentas, lo que le ofrece límites hasta n veces más altos.

Tenga cuidado al cerrarse accidentalmente si está tratando de encontrar a otros usuarios haciendo esto, si no está permitido para los clientes.


Dado que su propio cliente JavaScript está accediendo a la API directamente, cualquiera podrá ver lo que está haciendo e imitarlo, incluido el uso de la misma clave API. Puede intentar que sea más difícil, como ofuscando su código o poniendo varios obstáculos en el camino, pero usted y la persona que está tratando de restringir tienen básicamente el mismo acceso. En lugar de tratar de crear una diferencia en los privilegios, necesitará construir un sistema donde esté totalmente bien que el cliente no oficial use todo el acceso en su alcance, pero el sistema está organizado de tal manera que el uso oficial en todos los clientes sea mayor

Esto a menudo se realiza con tokens de acceso por usuario, en lugar de un token para toda la aplicación. El límite de cada token debe ser suficiente para el uso típico de su API, pero restrictivo para alguien que intente abusar de él. Por ejemplo, 100 llamadas por minuto pueden ser más que suficientes para admitir la navegación típica, pero si quiero eliminarlo, no puedo hacerlo efectivamente con ese presupuesto.

Siempre habrá una carrera armamentista: puedo superar el límite creando muchas cuentas de usuario de bot. Sin embargo, ese es un problema bastante resuelto si solo agrega un captcha a su flujo de registro, con un pequeño gasto para el humano real. Cuando entras en estos escenarios, todo es solo una compensación entre conveniencia y restricción. Nunca encontrarás algo totalmente a prueba de balas, así que concéntrate en hacerlo lo suficientemente bueno y espera a que alguien te explote para saber dónde estaban los agujeros.


Desafortunadamente, no hay una solución perfecta para esto.

El enfoque general suele ser proporcionar una forma engañosa para que los clientes se identifiquen (por ejemplo, un identificador, una versión y una clave API, por ejemplo), para que los clientes registren información sobre ellos mismos que pueda usarse para limitar el acceso (por ejemplo, el cliente es un servidor en un rango de direcciones IP dado, por lo que solo permite llamadas en ese rango; por ejemplo, el cliente es JavaScript, pero se entrega solo a una categoría específica de navegador, por lo que solo permite el acceso a solicitudes HTTP que especifican ciertas cadenas de agente de usuario; etc.) , y luego usar el aprendizaje automático / reconocimiento de patrones para detectar el uso anómalo que probablemente sea un cliente falso y luego rechazar el tráfico de estos clientes falsificados (o confirmar con los clientes que estos usos no provienen del cliente legítimo, reemplace sus credenciales falsas , y luego no permitir más tráfico con las credenciales falsas más antiguas).

Puede hacer que sea un poco más difícil falsificar usando varias capas de clave. Por ejemplo, proporciona una credencial de mayor duración que vive en un servidor (y que solo puede usarse en un conjunto limitado de rangos de direcciones IP) para realizar una llamada a la API que registra información sobre el cliente (por ejemplo, el agente de usuario) y devuelve una clave del lado del cliente de menor duración que está sindicada en JavaScript para su uso en el cliente para solicitudes de API del lado del cliente. Esto también es imperfecto (un spoofer podría emitir la misma llamada al servidor para obtener la credencial), pero será más difícil si la clave API devuelta se incluye en JavaScript o HTML ofuscado (y que cambia con frecuencia) (lo que dificultaría extraer de manera confiable de la respuesta). Eso también proporciona una manera de detectar más fácilmente la suplantación de identidad; la clave del lado del cliente ahora está vinculada a un cliente en particular (por ejemplo, un agente de usuario específico, tal vez incluso un contenedor de cookies específico) que hace que la reutilización en otro cliente sea fácil de detectar y la caducidad también limita la duración en la que la clave falsificada puede reutilizarse.


Podría intentar generar una ID de sesión única, vinculada a una determinada dirección IP / usuario y un tiempo limitado de vida. Cuando un usuario descarga el código JavaScript de la interfaz de su aplicación, inyecte la ID de sesión generada en el código fuente JavaScript. El ID de sesión se adjuntará a cada solicitud a su API y se levantará el límite de velocidad.

La ID no se puede copiar simplemente para suplantación de identidad, ya que solo es válida para una única dirección IP, usuario y tiempo limitado. Por lo tanto, un adversario tendría que llamar a su página y filtrar la clave de su fuente de JavaScript o interceptar la solicitud de Ajax cada vez que un nuevo usuario quiera usarla.

Otra opción:

Configure un proxy para su propia aplicación y use ofuscación. Las solicitudes de Ajax al proxy usan diferentes nombres de las llamadas API reales y el proxy las traduce de nuevo. Por lo tanto, su aplicación no llamará a getDocument en su API real, pero llamará a getFELSUFDSKJE en su proxy. El proxy traducirá esta llamada de vuelta a getDocument y la reenviará a la API con tarifa limitada real.

Su API real no calificará las solicitudes de límite del proxy.

Y para que otras personas no usen su proxy para su propia aplicación, cambie el esquema de ofuscación diariamente. Los nombres de llamadas ofuscados pueden generarse automáticamente en su código fuente JavaScript y configurarse en el proxy.

Un cliente que desee usar esto, también necesitaría mantenerse al día con su ofuscación cambiante para usar su proxy. Y aún puede usar encabezados de referencia y similares para el registro, por lo que puede encontrar personas que usan su proxy. O atraparlos al cambiar el esquema de ofuscación.


Si esto le causa un problema, causará un problema a su supuesto ecosistema de desarrolladores (por ejemplo, cuando intenten desarrollar una IU alternativa). Si realmente está comiendo su propia comida para perros, haga que la API (y la limitación de velocidad) funcionen para su aplicación. Aquí hay algunas sugerencias:

  • No califique el límite por dirección IP. Más bien, limite de velocidad por algo asociado con el usuario, por ejemplo, su ID de usuario. Aplique el límite de velocidad en la etapa de autenticación.

  • Diseñe su API para que los usuarios no necesiten llamarla continuamente (por ejemplo, dar una llamada de lista que devuelva muchos resultados, en lugar de una llamada repetida que devuelva un elemento cada vez)

  • Diseñe su aplicación web con las mismas limitaciones que espera que tenga su ecosistema de desarrollador, es decir, asegúrese de poder diseñarla dentro de tasas de aceleración razonables.

  • Asegúrese de que su back-end sea escalable (preferiblemente horizontalmente) para que no tenga que imponer una aceleración a niveles tan bajos que en realidad causen un problema a una interfaz de usuario.

  • Asegúrese de que su estrangulamiento tenga la capacidad de hacer frente a las explosiones, así como limitar el abuso a largo plazo.

  • Asegúrese de que su estrangulamiento realice acciones sensatas adaptadas al abuso que desea eliminar. Por ejemplo, considere hacer cola o retrasar a los abusadores leves en lugar de rechazar la conexión. La mayoría de los front-end web solo abrirán cuatro conexiones simultáneas a la vez. Si demoras un intento de abrir un quinto, solo encontrarás el caso en el que están usando una CLI al mismo tiempo que el cliente web (o dos clientes web). Si retrasa la enésima llamada API sin un espacio en lugar de fallar, el usuario final verá que las cosas se ralentizan en lugar de interrumpirse. Si combina esto con solo poner en cola llamadas N API a la vez, solo afectará a las personas que están paralelizando un gran número de llamadas API, lo que probablemente no sea el comportamiento que desea, por ejemplo, 100 llamadas API simultáneas, por lo general, una brecha de una hora suele ser lejana. peor que 100 llamadas secuenciales de API en más de una hora.

¿Esto no respondió a tu pregunta? Bueno, si realmente necesita hacer lo que está pidiendo, limite la velocidad en la etapa de autenticación y aplique un límite de velocidad diferente según el grupo en el que se encuentre su usuario. Si está utilizando un conjunto de credenciales (utilizado por sus desarrolladores y equipo de control de calidad), obtendrá un límite de tasa más alto. Pero puede ver de inmediato por qué esto inevitablemente lo llevará a su ecosistema viendo problemas que su equipo de desarrollo y control de calidad no ve.


Suponiendo que la aplicación en cuestión debe estar abierta públicamente, no tiene muchas opciones:

Elija otra forma de demostrar el poder de su API. Por ejemplo, escriba dicha aplicación y comparta su fuente, pero en realidad no ejecute ese código. Sin embargo, asegúrese de que esté bien documentado, para que cualquiera pueda implementarlo y verlo funcionando (sujeto a limitación).

La aplicación que ejecute necesitaría ser refactorizada para evitar solicitudes de API del lado del cliente y estar más representada por el servidor. Todavía puede mejorar su API, pero no de una manera obvia: realice solicitudes seguras a una API sin aceleración desde el lado del servidor.

Ajuste la limitación de velocidad para permitir que su aplicación funcione e invierta en la optimización del rendimiento para manejar la carga.

Y sí, tenga el núcleo de la API libre de aceleración en primer lugar, y manténgalo dentro de una red privada. Acelerar en una capa separada de acceso público.


  • Direcciones IP de origen de la lista blanca
  • Use una VPN , haga una lista blanca de miembros VPN
  • La solución de proxy o el complemento del navegador que agrega encabezados HTTP debería estar bien si puede proteger el proxy y no le preocupan los ataques MITM rastrean el tráfico
  • Cualquier solución que implique secretos puede mitigar el impacto de las fugas al rotar los secretos diariamente