2016-10-17 32 views
1

json-serverをバックエンドとして使用するシンプルなBackbone.jsアプリがあります。私はログインする機能を持っていますが、それはコレクションからユーザーを見つけますが、セッションを保存する方法はわかりません。私は後ですべてのリダイレクトでチェックされるクッキーにパラメータを保存することを考えました。ここに私のモデルである:セッションパラメータをクッキーに保存する

var User = Backbone.Model.extend({ 
    defaults: { 
     login: '', 
     password: '', 
     authToken: '' 
    } 
}); 

そして、ここに私のコレクションです:

var UserCollection = Backbone.Collection.extend({ 
    url: 'http://localhost:3000/users', 

    // creates a random token 
    setToken: function() { 
     var rand = function() { 
      return Math.random().toString(36).substr(2) 
     } 

     var token = rand() + rand(); 
     this.set({authToken: token}); 
    } 
}); 

そして、これは、ログイン機能を備えた図である

var LoginView = Backbone.View.extend({ 
    initialize: function() { 
     this.collection = new UserCollection(); 
     // template 
    } 
    // render function omitted 

    signIn: function() { 
     var login = $('#login').val(); 
     var password = $('#password').val(); 

     /** 
      finds a user within with the values from input fields 
      inside the collection 
     */ 
     if (login && password) { 
      this.collection.fetch({ 
       data: { 
        login: login, 
        password: password 
       } 
      }); 
     } 
    } 
}); 

この機能は私に一つのオブジェクトの配列を返します私の要求されたモデルです。私が必要とするのは、私のsetTokenメソッドを使用し、このモデルのauthTokenをクッキーに保存して、アプリのどこかで使用できるようにすることですが、実際にその方法を知ることはできません。

答えて

1

モデルを使用して認証を処理すると、コレクションよりも理にかなっています。モデルの責任をシンプルにし、一つのものに限定してください。認証を処理するモデル、次に認証される必要のある他のオブジェクトへの呼び出しを処理するモデルです。同時に処理することはできません。

私はBackbone-sessionのモデルの個人認証に基づいています。

// Using CommonJS 
var Session = require('backbone-session'); 

// Extend from Session to implement your API's behaviour 
var Account = Session.extend({ 
    urlRoot: 'http://localhost:3000/users', 
    signIn: function(opt) { 
     opt = opt || {}; 
     opt.data = _.extend({}, { 
      login: opt.login, 
      password: opt.password 
     }, opt.data); 
     return this.fetch(opt); 
    }, 
    signOut: function(opt) { /** handle logout */ }, 
    getAuthStatus: function() { /** handle refetching if needed */ } 
}); 

私はアプリケーションにサービスとして公開しています。このsessionモジュールでは、すべてのモデルまたはコレクションのAPIに対するその後の呼び出しごとに、認証を確実にするためにBackbone.Syncをオーバーライドします。

var mySession = new Account(); 


Backbone.sync = (function(syncFn) { 
    return function(method, model, options) { 
     options = options || {}; 

     var beforeSend = options.beforeSend, 
      error = options.error; 

     // Add auth headers 
     options.beforeSend = function(xhr) { 
      xhr.setRequestHeader('Authorization', "Bearer " + mySession.get('authToken')); 
      if (beforeSend) return beforeSend.apply(this, arguments); 
     }; 

     // handle unauthorized error (401) 
     options.error = function(xhr, textStatus, errorThrown) { 
      if (error) error.call(options.context, xhr, textStatus, errorThrown); 
      if (xhr.status === 401) { 
       mySession.signOut(); 
      } 
     }; 

     return syncFn.apply(this, arguments); 
    }; 
})(Backbone.sync); 

バックボーンセッションのモデルでは、ローカルストレージをバックエンドとして使用しています。独自のsyncビヘイビアの代わりにローカルストレージを使用するのは、sync method is overridenです。なぜローカルストレージ

sync: function(method, model, options) { 
    options = options || {}; 
    var url = model.options.url || model.url; 
    var key = _.isFunction(url) ? url() : '' + url; 
    var response; 
    switch (method) { 
    case 'create': 
    case 'update': 
     var data = model.toJSON(); 
     var text = JSON.stringify(data); 
     response = localStorage.setItem(key, text); 
     break; 
    case 'delete': 
     response = localStorage.removeItem(key); 
     break; 
    case 'read': 
     response = JSON.parse(localStorage.getItem(key)); 
     break; 
    } 
    if (_.isFunction(options.success)) { 
    options.success(response); 
    } 
    return Backbone.$.Deferred() 
    .resolve(response) 
    .promise(); 
}, 

この実装を使用して、Cookieを使用するように最小限に変更できます。

私のAPIは別のドメインにあり、CORSを使用してパブリックアクセスを可能にしているので、ローカルストレージは私にとっては良い選択でした。 Safari has limitation on cookies.

Safariは訪問されていないサイトからのクッキーを直接ブロックします 。あなたはセキュリティ設定で見ることができます。 のデフォルト設定は「Cookieを受け入れる」です:「私がアクセスしたサイトからのみ」。

関連する問題