2011-10-16 28 views
28

Estoy intentando crear una aplicación móvil con PhoneGap, jQuery Mobile y Backbone.js en el lado del cliente, con una API Rails 3 JSON ejecutándose en el servidor.¿Cómo utilizar la autenticación de tokens con Rails, Devise y Backbone.js?

Sé cómo recuperar el token del servidor después de ser autenticado, pero no sé cómo anexar la clave/valor "token_auth" a todas las solicitudes AJAX que Backbone.js realizará en mi servidor.

Aquí está mi flujo en la actualidad

  1. tipos de usuario en algunos campos de formulario y éxitos "Acceder"
  2. Backbone crea un nuevo objeto del jugador con el correo electrónico y la contraseña de información.
  3. Tengo un Player.authenticate que establece el testigo a AUTHENTICATION_TOKEN
  4. Todas las solicitudes después de esto debe añadir "auth_token =" + AUTHENTICATION_TOKEN

He mirado en http://documentcloud.github.com/backbone/#Sync para tal anulando la llamadas AJAX - pero eso parece bastante extremo para esta simple tarea.

¿Alguien tiene alguna experiencia con la ejecución Devise token_authentication y Backbone.js?

Respuesta

14

¿Por qué no anexarlo a todas sus solicitudes jquery ajax? Agregará auth_token a todas sus llamadas ajax a través de jQuery. Eso podría ser útil cuando se trabaja directamente con jQuery ajax (o libs que lo hacen). Pero esto también podría ser un problema de seguridad (cuando tienes llamadas ajax a otros sitios ...).

// this is untested 
$.ajaxSetup({ beforeSend : function(xhr, settings){ 

    // just because the auth_token is a private information 
    if(!settings.crossDomain) { 

    // parse data object 
    var dataobj = JSON.parse(xhr.data); 

    // add authentication token to the data object 
    dataobj.auth_token = AUTHENTICATION_TOKEN; 

    // save the dataobject into the jqXHR object 
    xhr.data = JSON.stringify(dataobj); 

    } 
}}); 

Otro enfoque puede ser escribir esa señal en la cabecera y procesarlo en el lado del servidor:

// thats not beautiful 
$.ajaxSetup({ headers : { "auth_token" : AUTHENTICATION_TOKEN } }); 
+0

¡Realmente me gusta este enfoque! ¡Es descriptivo y más cercano a lo que intento lograr! Gracias :) – theodorton

+1

Sí, el enfoque es más limpio. Sin embargo, no es necesario analizar y codificar datos, el token de autenticación se puede enviar usando encabezados HTTP. Además, no es necesario en las solicitudes GET. Actualicé la demostración: http://jsfiddle.net/dira/ZcY3D/18/ – dira

+0

solo para el futuro: es capaz de autenticarse a través de campos de encabezado http personalizados como una característica de diseño o es una convención de rieles para listarlos en el controlador # params? – abstraktor

26

La clave consiste en introducir en el método Backbone.sync.

Echa un vistazo a esta aplicación: https://github.com/codebrew/backbone-rails/blob/master/vendor/assets/javascripts/backbone_rails_sync.js

puedes añadir a sí mismo de esta manera:

Backbone.old_sync = Backbone.sync 
Backbone.sync = function(method, model, options) { 
    var new_options = _.extend({ 
     beforeSend: function(xhr) { 
      var token = $('meta[name="csrf-token"]').attr('content'); 
      if (token) xhr.setRequestHeader('X-CSRF-Token', token); 
     } 
    }, options) 
    return Backbone.old_sync(method, model, new_options); 
}; 

Control hacia fuera este violín: http://jsfiddle.net/dira/ZcY3D/14/

+0

Esta es una forma programáticamente buena de resolver el problema, pero me gusta el código que está un poco más cerca de una "solución" textual para el problema. Aunque esto funcionará, supongo :) – theodorton

+1

No volvimos para ver esta pregunta, y el motivo por el que esta respuesta no está marcada como aceptada es porque usa el token CSRF. Aunque uno podría simplemente cambiar la línea 'var token =' para que funcione con cualquier otra variable. – theodorton

+1

no olvide devolver el old_sync "return Backbone.old_sync (method, model, new_options);" para mantener el encadenamiento y evitar problemas en las nuevas versiones principales. – panchicore

1

crear una función como ésta, que lo enviará cada vez que se envía una solicitud ajax al servidor

$(function(){ 
    $(document).ajaxSend(function(e, xhr, options) { 
     var token = $("meta[name='csrf-token']").attr("content"); 
     xhr.setRequestHeader("X-CSRF-Token", token); 
    }); 
}) 
Cuestiones relacionadas