2011-04-27 94 views
41

首先,应该为应用服务的静态页面是登录页面吗?backbone.js - 处理用户是否登录

其次,我的服务器端代码是好的(它不会给任何用户不应该能够看到的数据)。但是,如何让我的应用程序知道如果用户未登录,要返回登录表单?

回答

14

我有一个后端调用,即我的静态页面(index.php)用来检查当前用户是否登录的客户端代码。假设您有一个后端调用api/auth/logged_in,它返回HTTP状态代码200如果用户登录或以其他方式400(使用基于cookie的会话):

appController.checkUser(function(isLoggedIn){ 
    if(!isLoggedIn) { 
     window.location.hash = "login";  
    } 

    Backbone.history.start(); 
}); 

... 

window.AppController = Backbone.Controller.extend({ 

    checkUser: function(callback) { 
    var that = this; 

    $.ajax("api/auth/logged_in", { 
     type: "GET", 
     dataType: "json", 
     success: function() { 
     return callback(true); 
     }, 
     error: function() { 
     return callback(false); 
     } 
    }); 
    } 
}); 
+0

你会如何检查是不断收到任何数据之前?所以,当应用程序调用数据时,它会检查它们是否已登录。如果没有,它将进入登录页面。 – Matthew 2011-04-29 14:48:48

+9

如果你想对后端的每一次调用进行检查,你应该把它与你的后端代码集成在一起。例如,如果用户没有对任何*呼叫进行认证,那么你可以从后端返回一个'401 Unauthorized'或者你可以在客户端捕获的东西。 这样,您不必在每次数据请求之前分别打电话来检查授权。 在这种情况下,您可能必须重写'Backbone.sync'方法来捕获'401 Unauthorized'并发出一些事件,您可以使用它来检测后端调用是否未经授权。 – Sam 2011-04-29 17:37:25

+1

请仔细阅读↓ – user2398029 2013-05-19 19:35:55

69

我使用会话概念来控制用户登录状态。

我有一个SessionModel和SessionCollection这样的:

SessionModel = Backbone.Model.extend({ 
    defaults: { 
     sessionId: "", 
     userName: "", 
     password: "", 
     userId: "" 
    }, 

    isAuthorized: function(){ 
     return Boolean(this.get("sessionId")); 
    } 

}); 

在应用程序启动,我初始化一个全局变量,activeSession。开始时,这个会话是未经授权的,任何绑定到这个模型实例的视图都可以相应地渲染在登录尝试时,我首先通过使会话无效退出。

logout = function(){ 
    window.activeSession.id = ""; 
    window.activeSession.clear(); 
} 

这将触发任何视图,监听activeSession,并将我的主视图进入登录模式,它将提出登录提示。然后我得到了用户的用户名和密码,并把它们放在这样的activeSession:

login = function(userName, password){ 
    window.activeSession.set(
     { 
      userName: userName, 
      password: password 
     },{ 
      silent:true 
     } 
    ); 
    window.activeSession.save(); 
} 

这将通过backbone.sync触发更新到服务器。在服务器上,我设置了会话资源POST操作,以便它检查用户名和密码。如果有效,它会填写会话上的用户详细信息,设置唯一的会话ID并删除密码,然后发回结果。

然后,我的backbone.sync被设置为将window.activeSession的sessionId添加到对服务器的任何传出请求。如果会话Id在服务器上无效,它将发回一个HTTP 401,该HTTP 401会触发注销(),导致显示登录提示。

我们还没有完成实现,所以可能会出现逻辑错误,但基本上,这是我们如何处理它。另外,上面的代码不是我们的实际代码,因为它包含更多的处理逻辑,但它是它的要点。

+0

我其实已经改变了一下行为。我知道通过sessionCollection.create()创建新的会话,然后触发任何视图都可以收听的全局可用loginSuccess消息。 – 2011-05-09 20:55:06

+0

你的方法听起来不错。任何机会,你可以分享你的更新代码的要点? :) – dbau 2012-04-26 08:13:25

+0

不幸的是,由于后端存在问题(我们希望在后端使用现成的身份验证系统),我们将此解决方案从单独的身份验证机制(现在基于Cookie)移开了。 – 2012-04-26 11:58:01

-14

我认为你应该做这个服务器只片面...有得到它砍死单元,除非你有某种神奇的API的响应它

+8

你应该把它做成服务器端,但如果你不依赖它,检测客户端上的登录状态没有任何问题。 – 2011-12-29 07:10:52

2

我想你不应该只控件的HTML的很多机会显示还可以控制显示数据。因为用户可以使用Firefox来改变你的JavaScript代码。

有关详细信息,您应该在用户登录后向用户授予令牌,并且每次他或她访问您的组件(如数据网格或树等)时,页面都必须获取这些数据(可能是json)从你的web服务,web服务将检查这个令牌,如果令牌不正确或过期,你不应该给用户数据,而应该给出错误消息。因此,即使用户使用萤火虫更改js代码,用户也无法破解安全。

这可能对您有所帮助。