2016-10-05 24 views
2

私たちはサブアプリケーション/モジュールを備えた大きなマリオネットアプリを持っています。Backbone Marionetteの認証ルートと公開ルート

これらはそれぞれApp.addInitializer内に独自のルータを登録します。

特定のルートを公開するには、などの認証に必要なものとしてフラグを立てるには、とは何ですか?

私は、ユーザーが認証されているかどうかをチェックする方法がありますが、すべてのルートハンドラでそのチェックを実装する必要はありません。

PrivateModuleRouter.Router = Marionette.AppRouter.extend({ 
    appRoutes: { 
    "privateRoute(/)" : "handlePrivateRoute", 
    } 
}); 

var API = { 
    handlePrivateRoute: function() { 

    //I don't want to repeat this everywhere.. 

    if(!Auth.isAuthenticated()) { 
     App.navigate('/login', {trigger:true}); 
    } else { 
     PrivateRouteController.showForm(); 
    } 
}; 

App.addInitializer(function(){ 
    new PrivateModuleRouter.Router({ 
    controller: API 
    }); 
}); 

フラグへのルート定義での方法は、それがプライベートとしてあり、その後、トップレベルのルートハンドラは、このチェックを実行しますか?

それはしかしRouterイベントにならルートハンドラを直接トリガされた場合、これはtrigger:trueを渡し、直接API.handlePrivateRoute()を呼び出していない(トリガしない場合があり

+0

はあなたにできましたこの問題を解決するために?答えがあなたを助けたら、それを受け入れるか、何も助けなければあなた自身の答えを作ります。 –

答えて

0

免責事項:私は個人的にマリオネットを使用しないように、この答えは唯一のバックボーンに基づいています。

実行機能

バックボーンは、ロジックのようなものを処理するための方法として、ルータでexecute機能を提供します。でもexampl各ルータで実行繰り返さないようにする認証ルータ

一つの方法は、アプリの拠点ルータを作ることであろう

var Router = Backbone.Router.extend({ 
    execute: function(callback, args, name) { 
    if (!loggedIn) { 
     goToLogin(); 
     return false; 
    } 
    args.push(parseQueryString(args.pop())); 
    if (callback) callback.apply(this, args); 
    } 
}); 

:eはそれで認証ロジックを持っています。特定のルータ

の定義

var BaseRouter = Backbone.Router.extend({ 
    constructor: function(prefix, opt) { 
     // get the hash 
     this.auth = _.result(this, "auth", {}); 
     BaseRouter.__super__.constructor.apply(this, arguments); 
    }, 

    // requires auth by default? 
    authDefault: false, 

    /** 
    * Check the `auth` hash for a callback. Returns `authDefault` if 
    * the callback is not specified. 
    * @param {String} callbackName name of the function. 
    * @return {Boolean} true if the callback is private. 
    */ 
    hasAuth: function(callbackName) { 
     return _.result(this.auth, callbackName, this.authDefault); 
    }, 

    // To easily override the auth logic in a specific router 
    checkAuth: function(){ 
     return Auth.isAuthenticated(); 
    }, 

    execute: function(callback, args, name) { 
     if (this.hasAuth(name) && !this.checkAuth()) { 
      this.navigate('/login', { trigger: true }); 
      return false; 
     } 
    } 
}); 

次に、あなたのルーターのそれぞれに対して、BaseRouterを拡張します。
var SpecificRouter = BaseRouter.extend({ 
    routes: { 
     '*otherwise': 'home', // notice the catch all 
     'public': 'publicRoute', 
     'private': 'privateRoute', 
     'unspecified': 'defaultAccessRoute' 
    }, 

    /** 
    * The auth hash works like this: 
    * "functionName": [boolean, true if needs auth] 
    * 
    * home and publicRoute could be left out as it's the default here. 
    */ 
    auth: { 
     home: false, // public 
     publicRoute: false, // public 
     privateRoute: true, // needs authentication 
     // defaultAccessRoute will be public because BaseRouter 
     // defines `authDefault: false`. 
    }, 

    home: function() {}, 
    publicRoute: function() {}, 
    privateRoute: function() {}, 
    defaultAccessRoute: function() {}, 

}); 

そして、すべてのルートがデフォルトでプライベートにルータの

var PrivateRouter = BaseRouter.extend({ 
    authDefault: true, 
    routes: { 
     '*otherwise': 'home', // private 
     'only-private': 'onlyPrivate', // private 
    }, 

    // ...snip... 

    /** 
    * Optional example on how to override the default auth behavior. 
    */ 
    checkAuth: function() { 
     var defaultAuthResult = PrivateRouter.__super__.checkAuth.call(this); 
     return this.specificProperty && defaultAuthResult; 
    } 

}); 

0

githubのでは、ルータの実行前にいくつかのメソッドを呼び出すための多くの解決策を見つけることができます。 marionetteについては、フィルタシステムに基づく拡張子marionette-liteのアイデアを使用できます。

あなたはたとえばRequresAuthFilterのために、フィルタを定義する必要がありますように:

import { Filter } from 'marionette-lite'; 

const RequresAuthFilter = Filter.extend({ 
    name: 'requresAuth', // name is used in controller for detect filter 
    async: true, // async mode 
    execution: Filter.Before, 
    handler(fragment, args, next) { 
    // Requesting server to check if user is authorised 
    $.ajax({ 
     url: '/auth', 
     success:() => { 
     this.isSignedIn = true; 
     next(); 
     }, 
     error:() => { 
     Backbone.navigate('login', true); 
     } 
    }); 
    }, 
}); 

やショートの同期方法:

import { Filter } from 'marionette-lite'; 

const RequresAuthFilter = Filter.extend({ 
    name: 'requresAuth',  
    handler(fragment, args) { 
    if (!window.isSignedIn) { 
     Backbone.navigate('login', true); 
    } 
    }, 
}); 

としてControllerにこのフィルタを追加します。

const AppController = Marionette.Object.extend({ 
    // Add available filters map 
    filtersMap: [ 
     new RequresAuthFilter() 
    ], 

    filters: { 
    // e.g. Action that need authentication and if user isn't 
    // authenticated gets redirect to login page 
    requresAuth: ['logout', 'private'], 
    }, 

    logout() { /* ... */ }, 
    private() { /* ... */ } 
}); 
関連する問題