【问题标题】:How to detect expired user session in a react app?如何在反应应用程序中检测过期的用户会话?
【发布时间】:2017-08-16 04:15:20
【问题描述】:

我正在开发一个基于 Node / Express 的 REST API 和一个基于 React / Redux 的前端。用户可以登录(这使他们可以访问其他功能),但他们也可以在不登录的情况下使用基本功能。

当用户登录时,客户端使用凭据进行 HTTP 调用,服务器创建会话并返回用户对象(user_id 和一些其他数据)以及会话 cookie。 React 应用程序将用户对象保存在其 Redux 状态。在随后的 HTTP 调用中,用户通过 cookie 进行身份验证。

在渲染用户界面时,React 应用程序通过检查其状态中的用户对象来确定它是否已登录。这用于使某些仅对登录用户可用的按钮变灰,或在用户已登录时隐藏登录链接。

问题

会话可能会过期,或者用户在不同的浏览器选项卡中注销。 React 应用无法知道这一点,并认为它仍然处于登录状态(即应用状态与现实不匹配),从而导致错误的 UI 显示。

什么模式可以解决这个问题?

  • 在所有 Ajax 调用上添加一个钩子以检查 401 并更新 州?
  • 在 HTTP 标头中返回会话状态(然后?)
  • 服务器通知客户端它已被注销的彗星模式? (那时不再是 REST API)
  • 在实际 API 调用之前进行额外调用以确保用户仍处于登录状态? (看起来很浪费)

一旦客户端检测到它在正在进行的操作期间不再登录,如何处理?我更愿意在一个地方处理这个问题,而不是所有函数都进行 API 调用......

非常感谢您提供一些最佳做法!

【问题讨论】:

  • 为什么不只检查 cookie 或将 expires 属性添加到您的状态?无论如何,您还想检查 401 错误,因为您永远无法保证 cookie == 已验证/工作会话的存在

标签: reactjs session authentication express


【解决方案1】:

作为简单轮询的替代方法,您可以通过添加一个端点来使其更智能一些,该端点让您知道在该时间点为会话设置了多少秒超时。
然后在该时间之前 ping (而不是以特定的轮询率)并相应地更新。
在另一个选项卡中注销会返回一个无效的令牌,因此也会被拾起,但如果这是您的主要问题,则不会那么快。
为此,您可以使用broadcasting 让其他选项卡立即知道(或使用sessionStoragechange 事件在不受支持的浏览器上模拟广播)。

否则最好的方法是实现ServiceWorker;这些可以handle all requests for your app to the server。它是与您的应用程序分开的集中代码片段,它可以broadcast to all tabs 在看到它的一个请求被拒绝时丢失会话,并且您可以从这个地方有效地天真地进行轮询(而不是在每个单独的选项卡的运行时)。

【讨论】:

    【解决方案2】:

    在我能想到的 React 应用程序中,有两种直接的方法可以解决这个问题。两者都受到几天前我的一位同事的启发。

    1. 使用 SSE(服务器端事件)技术推送通知。正如您正确指出的那样,这会使您的 API 不那么纯粹。在需要完美的用户体验和/或您的服务器可能需要将其他通知推送到应用程序的情况下,这种方法应该是可以接受的牺牲。

    2. 在您的客户端应用程序中的某处(例如:setTimeout(...))建立一个短期计时器,定期调用将返回当前用户/会话信息的“ping”API 端点。这种方法会在超时期间影响用户体验,通常可以忽略不计,通常称为轮询。

    希望这会有所帮助!

    【讨论】:

    • 使用中间件怎么样?例如,使用 axios 添加响应中间件以在响应代码为 401 或 403 时触发注销操作。您认为这是个好主意吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 2014-02-20
    • 1970-01-01
    • 2019-06-10
    相关资源
    最近更新 更多