如何在react应用程序中检测过期的用户会话?

时间:2017-03-23 14:26:34

标签: reactjs session authentication express

我正在开发基于Node / Express的REST API以及基于React / Redux的前端。用户可以登录(这使他们可以访问其他功能),但他们也可以使用基本功能而无需登录。

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

在呈现用户界面时,React应用程序通过检查处于其状态的用户对象来确定是否已登录。这用于灰显一些仅供登录用户使用的按钮,或用于在用户登录时隐藏登录链接。

问题

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

要解决此问题的模式?

  • 勾选所有Ajax调用以检查401并更新 状态?
  • 在HTTP标头中返回会话状态(然后是?)
  • 服务器的Comet模式,通知客户端已注销? (不再是REST API)
  • 在实际API调用之前进行额外调用以确保用户仍然登录? (似乎很浪费)

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

我会感谢一些最佳做法!

2 个答案:

答案 0 :(得分:1)

我可以想到在React应用程序中有两种直接的方法来处理这个问题。两天前两位都是由我的一位同事启发的。

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

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

  3. 希望这有帮助!

答案 1 :(得分:0)

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

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