2011-10-16 37 views
28

Tôi đang cố gắng xây dựng một ứng dụng di động với PhoneGap, jQuery Mobile và Backbone.js ở phía máy khách - với một API JSON Rails 3 chạy phía máy chủ.Cách xác thực mã thông báo sử dụng với Rails, Devise và Backbone.js?

Tôi biết cách lấy mã thông báo từ máy chủ sau khi được xác thực, nhưng tôi không biết cách thêm khóa/giá trị "token_auth" vào tất cả các yêu cầu AJAX Backbone.js sẽ thực hiện cho máy chủ của tôi.

Dưới đây là dòng chảy của tôi vào lúc này:

  1. loại người dùng trong một số lĩnh vực hình thức và hit "Đăng nhập"
  2. Backbone tạo ra một đối tượng Player mới với email và mật khẩu thông tin.
  3. tôi chạy một Player.authenticate mà bộ token để AUTHENTICATION_TOKEN
  4. Mọi yêu cầu sau này nên thêm "auth_token =" + AUTHENTICATION_TOKEN

Tôi đã nhìn http://documentcloud.github.com/backbone/#Sync cho thể trọng AJAX gọi - nhưng điều đó có vẻ khá khắc nghiệt đối với nhiệm vụ đơn giản này.

Có ai có kinh nghiệm chạy Devise token_authentication và Backbone.js không?

Trả lời

14

Tại sao không thêm nó vào tất cả các yêu cầu ajax jquery của bạn. Nó sẽ thêm auth_token vào tất cả các cuộc gọi ajax của bạn trên jQuery. Điều đó có thể hữu ích khi làm việc trực tiếp với jQuery ajax (hoặc libs làm như vậy). Nhưng điều này cũng có thể là vấn đề bảo mật (khi bạn có cuộc gọi ajax đến các trang web khác ...).

// 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); 

    } 
}}); 

cách tiếp cận khác có thể viết mã thông báo rằng vào header và xử lý nó ở phía máy chủ:

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

Tôi thực sự thích cách tiếp cận này! Đó là mô tả và gần gũi hơn với những gì tôi đang cố gắng đạt được! Cảm ơn :) – theodorton

+1

Có, cách tiếp cận là sạch hơn. Tuy nhiên, không cần phải phân tích và xâu chuỗi dữ liệu, mã thông báo xác thực có thể được gửi bằng cách sử dụng tiêu đề HTTP. Ngoài ra, nó không cần thiết cho các yêu cầu GET. Tôi đã cập nhật bản trình diễn: http://jsfiddle.net/dira/ZcY3D/18/ – dira

+0

chỉ trong tương lai: có thể xác thực thông qua http headerfields tùy chỉnh một tính năng phát sinh hoặc là nó quy ước để liệt kê chúng trên bộ điều khiển # params? – abstraktor

26

Điều quan trọng là để giới thiệu nó trong phương pháp Backbone.sync.

Hãy nhìn vào thực hiện điều này: https://github.com/codebrew/backbone-rails/blob/master/vendor/assets/javascripts/backbone_rails_sync.js

Bạn có thể thêm nó cho mình theo cách này:

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); 
}; 

Check-out fiddle này: http://jsfiddle.net/dira/ZcY3D/14/

+0

Đây là một cách tốt để lập trình để giải quyết vấn đề, nhưng tôi thích mã đó gần hơn một chút về "giải pháp" văn bản cho vấn đề. Điều này sẽ làm việc mặc dù, tôi đoán :) – theodorton

+1

Chỉ cần không trở lại để xem xét câu hỏi này - và lý do câu trả lời này không được đánh dấu là chấp nhận là bởi vì nó sử dụng CSRF-token. Mặc dù người ta chỉ có thể thay đổi dòng 'var token =' để làm cho nó hoạt động với bất kỳ biến nào khác. – theodorton

+1

đừng quên trả lại old_sync "return Backbone.old_sync (phương thức, mô hình, new_options);" để giữ cho chuỗi và tránh các vấn đề về các phiên bản xương sống mới. – panchicore

1

Tạo một chức năng như thế này mà sẽ gửi nó bất kỳ khi nào yêu cầu ajax được gửi đến máy chủ

$(function(){ 
    $(document).ajaxSend(function(e, xhr, options) { 
     var token = $("meta[name='csrf-token']").attr("content"); 
     xhr.setRequestHeader("X-CSRF-Token", token); 
    }); 
}) 
Các vấn đề liên quan