Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.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
Backbone.js模板和视图安全性_Backbone.js - Fatal编程技术网

Backbone.js模板和视图安全性

Backbone.js模板和视图安全性,backbone.js,Backbone.js,首先,如果这是一个重复的问题,我道歉。我见过几个类似的问题,但它们没有提供我能理解的答案 我有一个Backbone.js应用程序,有很多视图/模板。有些视图只有在用户登录时才能访问,有些视图则不能访问。我知道如何保护底层REST调用,但我仍然不知道什么是检查特定视图(实际访问控制级别)的适当体系结构/设计。另外,在首次登录后存储和验证用户的正确方法是什么。 例如: 用户打开第一个视图,可以在其中列出产品。无需身份验证即可访问。但是如果用户这样做了,我需要将数据添加到REST调用中。因为响应将不同

首先,如果这是一个重复的问题,我道歉。我见过几个类似的问题,但它们没有提供我能理解的答案

我有一个Backbone.js应用程序,有很多视图/模板。有些视图只有在用户登录时才能访问,有些视图则不能访问。我知道如何保护底层REST调用,但我仍然不知道什么是检查特定视图(实际访问控制级别)的适当体系结构/设计。另外,在首次登录后存储和验证用户的正确方法是什么。 例如:

  • 用户打开第一个视图,可以在其中列出产品。无需身份验证即可访问。但是如果用户这样做了,我需要将数据添加到REST调用中。因为响应将不同(服务器端的推荐引擎)
  • 同一个用户尝试访问“添加新产品”模板,在该模板中他应该经过身份验证。我需要确保他是,如果不是,重定向到登录页面 我见过几种解决方案,但都像黑客

    什么是正确的、精心设计的方法

    谢谢, Elad.

    关于担保的假设 正如您所知,javascript是一种解释语言,因此它的源代码是人类可读的,即使是模糊的。因此,可以安全地假设一个邪恶的或未注册的用户(我们称他为Edward)可以访问应用程序的整个客户端代码。此外,根据模板加载机制,Edward可以完全读取html模板也是合理的假设

    鉴于上述假设,显然必须保护填充这些模板的数据。RESTAPI访问点必须强制执行某种身份验证机制,并在未经授权的访问情况下返回相关的错误消息

    有许多工具/中间件/框架可以实现良好的身份验证方案,其中大多数将使用会话对象来验证请求的状态(已授权、未授权),但这超出了本问题的范围

    处理未经授权的请求 假设您有一个在RESTAPI上工作的身份验证机制,下面是如何处理未经授权的访问

    需要登录 对于需要登录的所有数据,您可以保留HTTP响应代码,并在收到该代码时将应用程序导航到登录视图。正如您在其他问题中所看到的,您只需为与
    401-未经授权的
    http代码对应的每个错误响应设置回调(假设您的主干路由器是
    app.router
    ):

    现在,当此类请求需要重定向到登录表单时,您只需确保RESTAPI返回
    401

    分支情况 在更合理的情况下,您可能希望根据用户的状态将其重定向到不同的视图。在这些情况下,对RESTAPI的数据请求不应返回
    401
    ,因为它会被前一个回调截获。任何其他错误代码都应该执行
    403-禁止
    可能是适当的,或者
    400-错误请求
    ,这并不重要

    也就是说,当用户从主干路由器请求特定视图时,最好在渲染视图之前获取正确显示视图所需的数据。当您调用此特定数据时,如果用户没有获取该数据的正确凭据,您的服务器将返回一个带有错误代码的响应,该错误代码不会被应用程序截获,然后您可以对其进行分支。例如:

    // Assuming we are defining methods inside your backbone app router:
    
    listProducts : function() {
      var sensibleData = new app.SensibleData(),
          products = new app.Products();
          router = this;
      products.fetch();
      sensibleData.fetch({
        success : function( model, response, options ) {
          router.listProductsSignedIn( model, products );
        },
        error : function( model, response, options ) {
          router.listProductsNotSignedIn( products );
        }
    },
    
    listProductsSignedIn : function( sensibleData, products ) {
      //Create and show the full products view with all data
    },
    
    listProductsNotSignedIn : function( products ) {
       //Create and show the limited products view with the products data
    },
    //...
    
    等等,您有一个两步路由器,其中第二步根据用户的凭证进行分支,错误是由REST API上的一个单独访问点为未签名用户无法访问的敏感数据生成的。由于授权过程和强制执行由服务器管理,应用程序了解用户是否具有正确访问权限的唯一方法是尝试获取数据。然后,应用程序可以做出正确的反应

    存储用户信息 拥有一页javascript应用程序的一大优点是,您可以在应用程序的不同视图中保持状态。您可能希望在应用程序的某个状态中保持用户信息的可用性,以便正确地路由用户并显示适当的视图。您可能有一些可供用户使用的配置选项(语言、配置文件等)。此信息应通过REST调用提供,并作为成功登录的结果。用户登录后,您的应用程序将有一个已定义的用户,然后可以使用此状态显示正确的视图

    如果你没有为你的应用共享一个全局对象,那么让你的不同视图共享信息的一个好方法就是使用事件

    // Assuming you have defined a User model that has a proper route for authentication.
    var loginView = Backbone.View.extend({
      events : {'submit .login-form' : 'onLogin'},
      initialize : function() {
        this.model = new User();
        // here, we listen for the successful login event and we proxy it to the global
        // Backbone object in order to communicate with views that are out of scope.
        this.model.on('login:successful', function() { 
          Backbone.trigger('login:successful', this.model );
        });
      }
      onLogin : function() {
        var username = this.$('#username').val(),
            password = this.$('#password').val();
        this.model.authenticate({ 
          username : username, 
          password : password
        }); // this method should make a REST call and trigger an event on success
      }
    
    在主干应用程序路由器内:

    initialize : function() {
      // Here, we register to the successful login event and simply store the state of
      // a user inside of the router.
      this.listenTo( Backbone, 'login:successful', function( user ) {
        this.user = user;
      }, this );
    }
    
    现在,您可以在整个会话期间使用此状态,并使用它在路由中进行分支

    // Still in the router
    mainPage  : function() {
      if ( this.user ) {
        // show view for a registered user
      } else {
        // show a view for an unregistered user
      }
    },
    //...
    

    非常感谢您的详细回答。还有一条评论——我的视图在初始呈现时并不需要REST数据(在第一个视图中没有数据的简单表单生成)。我可以打电话给服务器只是为了验证是否允许用户这样做,但我想知道这样做是否有意义,或者只是将凭据保存在cookie中的某个地方。我希望它是清晰的,而不是胡说八道。您可以在主干应用程序中存储
    用户
    状态,以便知道如何根据该状态显示视图。我将更新我的答案以涵盖该案例。是的,加密会话cookie是保持用户凭据状态的好方法。如果任何人都有一个链接,指向一个好的教程,解释如何将cookie保存在本地,以便主干视图稍后用于身份验证,那就太好了。因为,这是空调
    // Still in the router
    mainPage  : function() {
      if ( this.user ) {
        // show view for a registered user
      } else {
        // show a view for an unregistered user
      }
    },
    //...