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