Proceso de autenticación asíncrono vs. Sincrónico

1

Actualmente estoy desarrollando una aplicación web que utiliza Node.js (JavaScript del lado del servidor) y MongoDB (base de datos NoSQL).

Estoy en la etapa en la que debo diseñar la autenticación y tuve una pregunta sobre la programación asíncrona.

Una de las ventajas de usar Node.js es que todo se puede programar para que sea asíncrono y, por lo tanto, no se bloquee cuando se realizan operaciones de E / S.

  • En el caso de la autenticación, ¿debo escribir todo de forma sincrónica?

Me temo que un atacante podría enviar correo no deseado a mi servidor con solicitudes que podrían llevar a la creación de cuentas duplicadas (u otros objetos) y, quizás, problemas de seguridad más adelante.

MongoDB no admite transacciones como SQL.

  • ¿Tengo derecho a preocuparme por los procesos de autenticación asíncrona?
pregunta Ko Ichi 19.06.2013 - 10:34
fuente

2 respuestas

1

El manejo de las solicitudes de forma síncrona en un servidor basado en eventos lo deja abierto a un DOS fácil, y ciertamente tiene un impacto muy negativo en el rendimiento. Independientemente del tipo de servidor que utilice, un sistema de autenticación robusto debería proporcionar cierta protección contra el escaneo de fuerza bruta.

La práctica más común que he visto para protegerme contra el escaneo de fuerza bruta es deshabilitar una cuenta después de un cierto número de inicios de sesión fallidos, lo que, en mi humilde opinión, es un DOS en sí. Un enfoque más práctico es el implementado por fail2ban: después de un cierto número de intentos fallidos de una dirección remota particular, esa dirección recibe una prohibición temporal en el firewall.

La solución que he usado en el pasado es implementar colas cortas para mutexes en el nombre de usuario y la dirección IP de origen: la autenticación no se prueba hasta que una solicitud tiene ambos mutex. Si cualquiera de las colas está llena, la solicitud falla inmediatamente. Esto todavía proporciona cierto alcance para DOS, pero su alcance debería estar mucho mejor contenido.

Todos estos se pueden manejar de forma asíncrona.

    
respondido por el symcbean 19.06.2013 - 11:52
fuente
1

Cuando se trata de sincronismo, una buena forma de pensar es sobre estado . Estado es lo que se debe conservar en el almacenamiento de datos (que puede ser RAM, disco, ... lo que sea, y no necesariamente en el servidor) para que el procesamiento pueda continuar y tener éxito.

Al hacer llamadas síncronas (genéricamente, no específicamente con Node.js), el llamante es un hilo de ejecución en alguna máquina, y el "estado" es lo que ese hilo de ejecución "sabe": su Posición actual en el código, sus variables locales, su pila de llamadas. La persona que llama conserva ese estado en la RAM durante la duración de la llamada; esa es la definición de una llamada síncrona: mientras la llamada no se termina, la persona que llama queda bloqueada. Los detalles pueden variar según el lenguaje de programación y cómo se interpreta / compila, pero para la mayoría de los lenguajes, cada hilo de ejecución (un concepto de lenguaje) se asigna en un hilo del sistema (un concepto de sistema operativo), que significa que el estado incluye una entrada en la tabla de subprocesos del sistema, un poco de espacio en las estructuras del programador y la pila de subprocesos .

Cada hilo del sistema tiene su propia pila, asignada cuando se creó el hilo. El tamaño predeterminado para esta pila depende del sistema operativo y puede ajustarse mediante programación. En Linux, una pila de hilos tiene un tamaño 1 MB de forma predeterminada. Eso es 1 MB de espacio de direcciones , no de RAM: las páginas reales se asignan cuando se accede a ellas, por lo que un hilo típico utilizará solo unas pocas docenas de kilobytes de "RAM verdadera". Aunque los detalles varían mucho según el contexto, la conclusión es la siguiente: en una aplicación típica, normalmente puede manejar unos pocos cientos de subprocesos a la vez, lo que significa que su servidor puede alojar unos pocos cientos en curso llamadas síncronas simultáneamente . Más allá de eso, debes pensar.

Llamadas asíncronas elimina esta gestión de estado basada en subprocesos: la persona que llama recupera el control inmediatamente y, por lo tanto, puede hacer otra cosa o incluso salir. Sin embargo, aún debe mantener algún estado en algún lugar, aunque solo sea para recordar que hay una llamada en curso y saber qué se debe hacer con el resultado. El punto de ir asíncrono es hacer una administración manual y precisa de este estado, que puede ser tan pequeño como un ID de sesión de 16 bytes o algún estado central similar, permitiendo así muchas más llamadas simultáneas. Dependiendo del contexto, es posible que incluso pueda descargar el estado en el cliente (lo que implica problemas de seguridad adicionales, por supuesto). Sin embargo, la implementación se vuelve mucho más compleja cuando se hace asíncrono, y la complejidad generalmente conlleva trabajo adicional, errores adicionales y, por lo tanto, vulnerabilidades adicionales.

Por lo tanto, ir asíncrono es una optimización y, por lo tanto, debe preverse solo si la situación hace que valga la pena la complejidad y el esfuerzo adicionales. Al igual que con todas las cosas relacionadas con el rendimiento, dichas optimizaciones deben retrasarse hasta que un problema grave real relacionado con el rendimiento haya sido debidamente detectado, monitoreado y medido. "La optimización prematura es la raíz de todo mal".

Por lo tanto, sugiero que primero escriba todo su código de forma sincrónica. Entonces, y solo entonces, las pruebas de rendimiento realistas le dirán si las llamadas sincrónicas serán suficientes o no; y si está justificado ir asíncrono, en ese momento sabrá mucho más acerca de su propia aplicación, lo que le permitirá estar preparado (o al menos más listo) para abordar la complejidad inherente de la programación asíncrona.

    
respondido por el Tom Leek 19.07.2013 - 15:19
fuente

Lea otras preguntas en las etiquetas