我正在开发基于Node / Express的REST API以及基于React / Redux的前端。用户可以登录(这使他们可以访问其他功能),但他们也可以使用基本功能而无需登录。
当用户登录时,客户端使用凭据进行HTTP调用,服务器创建会话并返回用户对象(user_id和其他一些数据)以及会话cookie。 React应用程序将用户对象保存在Redux状态。在随后的HTTP调用中,用户通过cookie进行身份验证。
在呈现用户界面时,React应用程序通过检查处于其状态的用户对象来确定是否已登录。这用于灰显一些仅供登录用户使用的按钮,或用于在用户登录时隐藏登录链接。
问题
会话可能会过期,或者用户在其他浏览器选项卡中注销。 React app无法知道这一点,并认为它仍然登录(即app状态与现实不匹配),导致UI显示错误。
要解决此问题的模式?
一旦客户端检测到它,如何在正在进行的操作期间不再登录?我宁愿在一个地方处理这个问题,而不是所有进行API调用的函数......
我会感谢一些最佳做法!
答案 0 :(得分:1)
我可以想到在React应用程序中有两种直接的方法来处理这个问题。两天前两位都是由我的一位同事启发的。
将SSE(服务器端事件)技术用于PUSH通知。正如您正确指出的那样,这会使您的API不那么纯净。这种方法应该是一个可以接受的牺牲,需要完美的UX和/或您的服务器可能需要将其他通知推送到应用程序。
在客户端应用中的某个位置建立一个短期计时器(例如:setTimeout(...)
),定期调用将返回当前用户/会话信息的“ping”API端点。这种方法会在超时时间内影响UX,通常可以忽略不计,通常称为轮询。
希望这有帮助!
答案 1 :(得分:0)
作为朴素轮询的替代方法,您可以通过添加一个端点来使其更聪明,该端点使您知道在该时间点将会话设置为多少秒超时。
然后在该时间之前ping(而不是以某个特定的轮询速率)并进行相应的更新。
在另一个选项卡中注销将返回无效令牌,因此也会被提取,但是如果这是您主要关注的问题,则不会那么快。
为此,您可以使用broadcasting立即通知其他标签(或使用sessionStorage
的change
事件在不支持的浏览器上模拟广播)。
否则,最好的方法是实现ServiceWorker;这些可以handle all requests for your app to the server。这是与您的应用程序分开的中央代码,可以broadcast to all tabs在看到一个请求被拒绝时立即丢失会话,并且您可以从该位置有效地天真地轮询(而不是在每个位置)标签的运行时)。