如何在 Knox 创建的令牌过期时强制注销?

How to force logout when Knox created token has expired?

我按照 Brad Traversy 的教程(https://www.youtube.com/watch?v=0d7cIfiydAc) using Knox for authentication and React/Redux for the frontend. Login/logout works fine (here is Brad's code: https://github.com/bradtraversy/lead_manager_react_django/blob/master/leadmanager/frontend/src/actions/auth.js --> 使用 POST 请求注销)开发了带有令牌身份验证的基于 Django 的 Web 应用程序,除了一个问题:当用户离开时长时间从计算机上,令牌同时过期。因此,当用户 returns 他仍然在网站的登录区域时,但是一旦他打开一个从数据库加载数据的 React 组件,控制台就会抛出 401 错误("Failed to load resource: the server responded with a status of 401 (Unauthorized)" ).然后用户必须继续 "logout" 并再次登录。

这不是最优的,我希望在用户returns之后,系统实现令牌到期并自动注销用户。我想到了以下方法,但我不确定如何实施或哪种方法最好:

1) 对于每个 API 请求:如果答案是 401 --> 注销(如果令牌未过期,这也可能使用户注销,但如果存在其他权限问题) - 对我来说似乎不是最佳选择。

2) 相反,也可以创建一条测试路线,例如api/auth/check 包含典型检查的 Django 视图

permission_classes = [permissions.IsAuthenticated]

如果返回 401 --> 注销。所以这意味着对于每个数据库请求,我之前都有另一个相当不明确的数据库请求。

3) 检查每个 API 请求,特别是令牌是否已过期 --> 怎么做?在文档 (https://james1345.github.io/django-rest-knox/) 中,我找不到检查令牌有效性的方法。我在数据库 table "knox_authtoken" 列中看到一个到期日期和一个巨大的代码 "digest" ,但这显然是加密数据,无法与其中的令牌值进行比较本地存储下的浏览器。

我很高兴收到关于如何最好地实施它的建议!

这可以通过多种方式完成。 我看不出自动将用户踢出的原因,但如果你想这样做,你可以:

  1. 创建一个 URL 仅用于每 5 秒左右检查身份验证是否有效
  2. 令牌过期后使用网络套接字发送实时消息。
  3. 把逻辑放在前端,比如存储token的有效期,运行一个超时,超时后让他重新登录。

Jazzy 的回答 - 选项 3 - 让我走上了正确的道路(谢谢!),但是在前端使用计时器最初并不成功,因为在 React 组件中启动计时器只会 运行 只要这个组件是可见的。我没有在用户会话期间始终可见的组件。我将 Django 设置中令牌的到期时间从默认值 8 小时更改为 72 小时,并使用此程序包对前端实施空闲检查:https://www.npmjs.com/package/react-idle-timer。因此,一旦我的应用程序 2 小时未被使用,我就会调用注销操作 (api/auth/logout)。使用这种方法,我不需要关心 Django 端令牌的到期时间,因为在 72 小时内没有用户会处于活动状态。只要他再次登录,他就会收到一个新的令牌。

新解决方案: 我决定不经常登录来打扰用户,并发现了这个不错的策略:

  • 我们选择永不过期 Knox 令牌
  • 我们将 Django 会话的到期日期设置为自上次登录后的 90 天
  • 如果用户超过 90 天未登录,他将在某个时候向后端发出请求(例如数据请求),我们会检查会话数据是否可用
if 'some_session_variable' in request.session:
    # whatever logic you need
else:
    return HttpResponse("logout")

由于会话变量在到期后将不可用,因此返回 'logout' 字符串。在前端,我们检查 'logout' 字符串的每个响应。如果它被返回,我们将启动注销过程。空闲计时器不再使用(因为根据我的经验它不太可靠)。