如何在客户端单页应用程序中管理服务器用户会话

Posted

技术标签:

【中文标题】如何在客户端单页应用程序中管理服务器用户会话【英文标题】:How to manage server user session within client side single page app 【发布时间】:2014-03-16 07:51:27 【问题描述】:

我一直在摸索不同的客户端技术,比如 AngularJS、EmberJS,甚至尝试直接使用 JQuery 并弄清楚如何使用 ReactJS。除此之外,我的目标是在客户端和 Java Jersey 2 jax-rs 后端 api 之间使用 json 构建单页应用程序。

我现在有两个绊脚石。虽然有些信息..我正在将我的应用程序部署为 Jetty 中的 WAR 文件。我的后端是基于java的。到目前为止,我只在客户端使用 jquery。

我的主要障碍是如何处理登录、注销和会话管理。使用休息 API 并使用 ajax,我可以登录,包括设置 cookie。然而,我担心的是单页应用程序,只有一个索引页面,如果用户关闭浏览器,然后在 cookie/会话仍然良好时将其重新打开到索引页面,用户应该登录,而不是查看外部(未登录)页面。我不确定如何处理这个问题,无论是 jsp 页面、带有一些模板库的 index.html 等等。使用 JSP,我可以插入一些 scriplet 代码(根据我的更好判断)。在过去,我会包含一个标头,该标头将检查 request.getSession().getAttribute("user") 是否存在..用户已登录并使用 scriplet if() 代码我会显示登录的标头,而不是未登录的标头。但我相信必须有更好的方法来使用当今的客户端 JS 框架来做到这一点。

另一个绊脚石是导航和动态方面。例如,当我在使用 Angular js 时,很容易使用 Welcome name 并在范围内将 name 替换为登录用户的 json 响应值。在我目前的情况下,除了在响应中使用某种 $("#elem-id").innerHtml="..." 代码之外,我不确定如何最好地使用纯 jquery 显示这样的动态位ajax 调用的成功方法。同样,我不太确定如何处理不同页面的导航。我登录的网站会有一些下拉菜单或链接,它们会用不同数量的内容替换内容区域。

首先,在 SPA 中处理用户会话的一些方法是什么,在页面重新加载或关闭/崩溃浏览器重新启动的情况下......以确保用户仍然登录并将他们引导到正确的页面?其次,存在哪些不需要我在一个 index.jsp 页面中放入大量代码的模板和路由/导航选项?

谢谢。

【问题讨论】:

你不觉得它长篇大论,谁有空读这个?尝试缩短您的问题,或者给我们一些您尝试过的代码。 @Rohan.. 不确定你是如何回答我的问题的?我在这里看到了更长的问题。我觉得我提供了所需的细节。如果内容太多,请不要阅读。没有人强迫你这样做。 【参考方案1】:

如果您将 REST API 作为后端,那么您必须将 oAuth 作为身份验证机制实现。也就是说,当您的用户使用用户名和密码登录时,您将使用身份验证令牌交换该数据。此身份验证令牌会随每个 API 调用发送给您的服务器,您的后端会在处理请求之前验证此令牌。到目前为止还清吗?

您可以做的是,当您获取访问令牌时,您还可以从服务器获取访问令牌过期时间并将该数据存储在您的客户端应用程序中。在 localStorage 也许?当您的用户关闭浏览器并再次重新打开时,您可以在要求用户登录之前先检查此类访问令牌是否可用(并且未过期)。这应该可以解决您的第一个问题。

其次,如果您正在寻找轻量级路由选项,我推荐director。

【讨论】:

我想我正在按照你所说的那样做一些事情。虽然在我的情况下.. 至少现在使用我的 jquery,在文档加载时,我对 API 进行 GET 检查以查看用户是否已登录。也许更好的选择是阅读 document.cookie 并查找我的服务器特定的cookie,而不是加载时的ajax请求?加载 ajax 请求背后的想法是,如果存在 cookie,请求将允许 ajax 处理程序使用 cookie 并验证用户/会话是否有效、未超时等。 好吧,既然您在每个请求上都验证用户的身份验证令牌,为什么要检查用户是否显式登录? 我实际上已经改变了我这样做的方式。我有幸不需要支持 IE9 或更早版本,因此决定使用本地存储来存储会话令牌,如果重新加载页面,我会在页面加载时检查会话令牌,如果找到,重定向用户到他们登录的仪表板。如果用户选择注销,我将删除会话令牌。例如,如果他们在几个小时后回来,在检查它是否过期时,它将被删除,他们将再次出现在主页上,然后他们可以再次登录。 这是最好的方法。我也是这样做的。我还维护本地存储的到期时间。这样,如果它过期了,我不需要调用服务器来将用户重定向到登录页面。 这是一个很好的观点......我将添加它。据我了解,localStorage 是安全的,因为它只能由同一服务器上的 javascript 访问。尽管客户端可以修改 localStorage 时间戳值,但是否有机会?没关系,因为每个请求都应该验证会话令牌+时间戳。【参考方案2】:

我正在构建一个类似的应用程序。 OAuth 不是强制性的。如果用户想要永久登录,您可以通过点击球衣登录端点并设置会话和 cookie“keepme”来进行正常会话等。然后您可以使用球衣 AuthFilter 例如检查是否有 cookie使用有效会话或活动会话并保持用户登录状态。

您的前端应用程序对此没有发言权,只需与服务器通信,如果它没有获得未经授权的访问(来自 AuthFilter)然后继续,否则它会显示登录页面。

【讨论】:

以上是关于如何在客户端单页应用程序中管理服务器用户会话的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Azure AD B2C 中管理用户流之间的单个帐户/会话

具有基于 HttpOnly cookie 的身份验证和会话管理的单页应用程序

web安全总结

#私藏项目实操分享#如何在答题小程序上快速接入客服消息系统

深信服上网行为管理如何配置双因素/双因子(2FA)身份认证

如何在 Restful WCF 服务中管理会话