Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 主干提线木偶中的认证和公共路由_Javascript_Authentication_Backbone.js_Marionette - Fatal编程技术网

Javascript 主干提线木偶中的认证和公共路由

Javascript 主干提线木偶中的认证和公共路由,javascript,authentication,backbone.js,marionette,Javascript,Authentication,Backbone.js,Marionette,我们有一个大型木偶应用程序,带有子应用程序/模块 每一个都在App.addInitializer中注册自己的路由器 var SpecificRouter = BaseRouter.extend({ routes: { '*otherwise': 'home', // notice the catch all 'public': 'publicRoute', 'private': 'privateRoute', 'unspec

我们有一个大型木偶应用程序,带有子应用程序/模块

每一个都在
App.addInitializer
中注册自己的路由器

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() {},

});
将某些路由标记为公共路由,将其他路由标记为需要身份验证的路由的最佳方法是什么

我在应用程序中有一种方法来检查用户是否经过身份验证,但我试图避免在每个路由处理程序中实现该检查

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
  });
});
路由定义中是否有方法将其标记为private,然后由顶级路由处理程序执行此检查

如果它在
路由器上
事件中,如果直接触发路由处理程序(不传递
触发器:true
,并直接调用
API.handlePrivateRoute()
),则可能不会触发此事件。

免责声明:由于我个人不使用木偶,此答案仅基于主干网

执行函数 主干网在路由器中提供了处理此类逻辑的功能。即使示例中也包含身份验证逻辑:

认证路由器 避免在每个路由器中重复执行的一种方法是为您的应用程序创建一个基本路由器

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

});

在github中,您可以找到许多在路由器执行之前调用某些方法的解决方案。对于
木偶
,您可以使用系统中基于扩展的思想

您应该将过滤器定义为,例如
requuresauthfilter

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);
      }
    });
  },
});
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() { /* ... */ }
});
或短同步方式:

import { Filter } from 'marionette-lite';

const RequresAuthFilter = Filter.extend({
  name: 'requresAuth',    
  handler(fragment, args) {
    if (!window.isSignedIn) {
      Backbone.navigate('login', true);
    }
  },
});
并将此过滤器添加到
控制器
,如下所示:

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);
      }
    });
  },
});
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() { /* ... */ }
});

你能解决这个问题吗?如果一个答案对你有帮助,你应该接受它,或者如果没有任何帮助,你应该创建自己的答案。