2012-06-06 10 views
9

No pude encontrar mucho sobre esto en ninguna parte. La mayoría de las aplicaciones de muestra simplemente no hablan de seguridad, etc. Suponga que el usuario será autenticado usando una llamada API basada en el resto. Cómo debe estructurarse la aplicación para que se encargue de la autenticación [También autorización]. Un puntero a la aplicación de muestra sería genial. Agregue vistas en términos de aplicación de una sola página, así como la aplicación normal. [Creo que cada vista debería ocuparse de ello]¿Cuál es la mejor práctica de diseño/arquitectura para gestionar la autenticación (sesión) y la autorización en una aplicación backbone.js

+1

Las aplicaciones de muestra no hablan de seguridad porque hay poco (si acaso) específico de Backbone para hablar. –

+0

Solo para que quede más claro, estoy interesado en los patrones de autenticación/autorización que se aplicarán sin comprometer la seguridad. p.ej. ¿Debería usar un patrón de mediador para guardar la información de sesión/autorización y cada vista debería verificar esta información antes de renderizarla? O si esto se soluciona por algún otro medio –

+0

Lo descubrí.La mejor manera es crear una ruta y vista principal llamada ruta/vista autenticada y derivar todas las rutas/vistas, que requieren que el usuario inicie sesión desde allí. agregar seguridad en las rutas no creará instancias de vistas innecesarias. La seguridad de la sesión, los parámetros de autorización, etc. deben obtenerse del servidor y cada solicitud debe validarse en el lado del servidor para mayor seguridad. También vea la respuesta de Anthony para manejar errores globales, etc. –

Respuesta

5

Encontré el mismo problema hace algunos meses haciendo una aplicación de una sola página que consume una API basada en REST. Lo que se me ocurrió después de buscar las respuestas fue usar el error 401 y 403 existente de HTTP. Tuve mi api devolver estos errores. Luego tomé las excepciones al usar un modelo extendido de manejo de errores para manejar estos errores y simplemente los enrute a mi inicio de sesión a través de la función de enrutador navigate.

var ErrorHandlerModel = Backbone.Model.extend({ 

    initialize: function(attributes, options) { 
     options || (options = {}); 
     this.on("error", this.errorHandler); 
     this.init && this.init(attributes, options); 
    }, 

    errorHandler: function(model, error) { 
     if (error.status == 401 || error.status == 403) { 
      app.history.navigate('login', true); 
     } 
    } 

}); 

En retrospectiva, aunque creo que habría sido mejor utilizar sólo una función global jQuery ajaxError lugar. El fragmento anterior se basó en un question posted here similar hace unos meses.

También tuve que anular el comportamiento de búsqueda predeterminado de la columna vertebral para poder desencadenar un error con el comando ogg para capturar una variable de respuesta incluida en la respuesta json de la API.

var Login = Backbone.Model.extend({ 

    urlRoot: '/login', 

    parse: function(resp,xhr) { 
     if (resp.response == 'success') { 
      app.history.navigate('dashboard', true); 
     } 
     else { 
      this.trigger('loginError');  
     } 
    return false; 
    } 
}); 
+0

Esto suena bien. ¿Dónde pusieron la verificación de autenticación ... estaba en vistas o en el controlador, p. digamos que el usuario aterriza en un panel después de iniciar sesión, ¿ingresa el código de autenticación en la creación de instancias del controlador o en vista? Creo que tiene sentido poner control de autorización en las vistas. Avísame si no estoy lo suficientemente claro. –

+1

Si por controlador se refiere al enrutador, sí, estamos haciendo una comprobación de autenticación en el enrutador, ya que tenemos funciones de usuario. Al mismo tiempo, también realizamos chequeos automáticos de vistas, por la misma razón que tuvimos que limitar algunos eventos a ciertos roles de usuario. Para los datos de usuario reales, estamos usando el modelo de inicio de sesión para almacenarlo y verificar el estado de la autenticación. Acabo de pegar una versión simplificada aquí. –

+0

genial. Muchas gracias. Antes de cerrar, ¿te importaría compartir un código de muestra? –

1

Acepto el comentario de Mu. Hay muy poco de qué hablar en términos de autenticación.

¿Cómo gestionas la autenticación con aplicaciones HTML estándar que se publican en tu servidor? Hazlo de esa manera porque así es como debería hacerse.

Para autorización, hay un poco más de qué hablar, pero no mucho. Esencialmente, solo le envía al usuario lo que se le permite ver. No hace código de autorización o autenticación en el navegador, a menos que sea absolutamente necesario. Y nunca es absolutamente necesario en mi experiencia.

JavaScript en un navegador no es seguro, por lo que no debe hacer cosas que dependan de la autenticación y autorización en el navegador.

escribí un pequeño artículo sobre algo de esto, aquí: http://lostechies.com/derickbailey/2012/01/26/modularity-and-security-in-composite-javascript-apps/

+0

Estoy de acuerdo con usted parcialmente, es decir, no debemos confiar en javascript por completo, pero mi pregunta es más específica para la aplicación de backbone.js, especialmente aplicaciones de una sola página donde las vistas, modelos, etc. lado del cliente. Ahora, una vez que obtengo el token de que el usuario está autenticado (y autorizado), ¿cómo debo usar ese token ... debo verificar el token en las vistas y luego procesarlo? También, ¿está lo suficientemente asegurado? –

+0

Estás bastante seguro en ese punto. Ya sea que esté utilizando un token que está enviando con cada solicitud o una cookie como la que usamos, básicamente está usando el token como un proxy para las credenciales del usuario y dependiendo del lado del servidor para usar ese proxy para buscar permisos verificar. Algo (cualquiera que sea ese algo) necesita ir con cada pedido, pero eso es todo. Descargábamos un conjunto de información adicional del lado del cliente que incluía indicadores de permisos que luego se podían utilizar al procesar para suprimir o revelar elementos de la interfaz, pero eso no es obligatorio. –

+0

@ Derick Bailey, he votado su respuesta por la única razón de que no veo respuesta en lo que se ha pedido. –

8

Tienes toda la razón en que la mayoría de las muestras no se ocupan de la seguridad en absoluto. Y como resultado, no tengo una gran muestra a la que pueda recomendarle. Solo puedo decirles cómo estructuramos nuestras propias cosas:

  1. Como usted sugirió, realizamos una llamada API para autenticar al usuario. En nuestro caso había una ID de sesión creada por el servidor Java tan pronto como como el usuario tocó la primera página (incluso antes de iniciar sesión) y se almacenó en un lado del cliente de cookies. Dado que esa cookie viaja con cada solicitud HTTPS al servidor (incluso las llamadas AJAX para obtener datos o realizan comandos) se asocia con un lado del servidor de cuenta particular una vez que el usuario se ha autenticado.

  2. Suponiendo que su transporte hasta el servidor es HTTPS y la cookie nunca viaja a través de Internet abierto, nadie puede espiar a ese valor y pretender ser que usuario conectado.

  3. En nuestro caso, el servidor está basado en Java y un filtro de servlet se sienta delante de todos de las funciones de la API que no son accesibles al público (es decir, los los que requieren inicio de sesión). Comprueba la sesión y se asegura de que represente a un usuario conectado antes de pasar la solicitud al servicio y que mantenga el código de servicio limpio de las comprobaciones de autenticación . Sin embargo, el código de autorización y la validación de parámetros actualmente se encuentran en el nivel de servicio .

  4. AJAX llama a la API puede fallar para autentificar incluso cuando lo hace comer una galleta que les acompañen para una variedad de razones (la sesión ha expirado, el servidor tenía que ser reiniciado y ha olvidado la sesión del usuario, el administrador cerró la sesión de manera forzada al usuario , etc.).En nuestra opinión, es importante que el servidor aún devuelva algo (es decir, no sea una respuesta vacía) y no debería ser algo así como un redireccionamiento a una página de inicio de sesión (que es inútil para una solicitud AJAX). Así que siempre devolvemos JSend protocol respuestas de todas nuestras funciones y si el usuario no está conectado, entonces el filtro de servlet devuelve una respuesta estándar de "error" JSend con un código particular. Eso nos permitió tener nuestro código del lado del cliente (que puede poner en una sincronización personalizada) aviso de que el usuario no ha iniciado sesión y solicitar un inicio de sesión. Es incluso posible, podría volver a intentar automáticamente la función después de iniciar sesión, pero eso es más sofisticado que el que tenemos.

  5. Al tener el aviso de sincronización de que el usuario no ha iniciado sesión o ha recibido una violación de seguridad no tiene que poner nada especial en las vistas. Simplemente hacen la solicitud que consideren apropiada y la prueba es correcta o no. Si es necesario un nuevo inicio de sesión , se activa a un nivel inferior.

  6. Cierre de sesión en realidad no necesita que mates a la cookie locales siempre que las marcas de servidores que dan sesión que ya no se registra en o descarta el registro de la sesión.

No estoy de acuerdo con la afirmación de Derick de que el cliente no debe saber sobre la seguridad. Creo que necesita saber cuándo solicitar el inicio de sesión, cómo decirle al servidor cuándo ejecutar el cierre de sesión, y siempre pienso que es una buena idea tener controles adicionales del lado del cliente para evitar el principio de sorpresa. Por ejemplo, preferiría que el cliente suprimiera las funciones de administración si no puedo usarlas en lugar de permitir que intente invocarlas y luego recibir un error en respuesta.

En última instancia, el servidor debe verificar los permisos del usuario nuevamente con cada solicitud (porque es muy fácil eludir la seguridad del lado del cliente), pero un buen UX requiere que el cliente sepa que no soy administrador y puede presentar el mejor representación de la IU para mí.

+0

Gracias John tiene sentido. Solo vea mi comentario a la respuesta de Derick y dígame cuáles son sus pensamientos. –

+0

Esta es una respuesta increíble. He estado pensando en estos mismos problemas. Gracias @John. Oye, ¿por qué es importante forzar el cierre de sesión en el servidor en lugar de simplemente anular la cookie o sesión local? No puedo pensar en una ventaja allí. – SimplGy

+0

@SimpleAsCouldBe No creo que pensáramos que era importante forzar el cierre de la sesión del servidor, sino que es cómo funcionó nuestro cierre de sesión. Lo activamos y el servidor sabía que estábamos desconectados. Luego, cualquier otro intento de hacer cualquier cosa por el lado del cliente tenía la garantía de obtener respuestas de falla y solicitar nuevos inicios de sesión. No estoy seguro si, una vez que haya eliminado una cookie del lado del cliente, si hay algo que otra persona con acceso a la máquina o al navegador pueda hacer para restaurarla y obtener acceso al servidor de sesión. –

Cuestiones relacionadas