django在另一个选项卡中检测用户登录

时间:2018-05-15 08:43:06

标签: python django csrf django-csrf

django中是否还有如果用户有两个打开的选项卡,两个都已注销,然后在一个选项卡中登录,告诉他已登录另一个选项卡?我的意思是像github那样告诉你已登录,请刷新页面。

现在问题是如果我在一个标签中登录,然后在第二个标签中登录,我会csrf token missing incorrect.

2 个答案:

答案 0 :(得分:1)

您得到csrf token missing incorrect.因为当用户重新登录时,服务器会为cookie生成一个新的csrf令牌。 Cookie会在同一个域中保留。当您尝试在当前页面上执行smth时,请求将失败,因为<form>中的csrf与已更改的cookie不同。这就是为什么github刷新页面(而不是承认从它做请求)。因此,服务器会将html中的新csrf返回到您的表单。

修改

考虑以下选择:

  • 如果您的cookie不是只读的:。设置setInterval,您可以在其中检查用户加载页面的会话以及来自cookie的当前会话。
  • 渲染4个第一个字符,并将其保存到变量中。页面加载时设置此变量。并且每个请求都使用标头传递变量。添加middleware,检查标头中的前4个字符是否匹配来自cookie的前4个字符,如果它没有告诉客户刷新页面。
  • 如果您想自动检测案例,则需要经常发送垃圾邮件并询问会话是否已更改。从客户端,您可以发送旧会话和新会话(如果会话是只读的,您可以从服务器发送少量的第一个字符)。

答案 1 :(得分:1)

我不知道github到底是怎么做到的。但有一种可能性是使用visibilitychange事件处理程序。切换选项卡时会触发此操作。事件处理程序可以检查当前站点的cookie,并确定是否有人登录了另一个选项卡。

https://developer.mozilla.org/en-US/docs/Web/Events/visibilitychange

通常标签不共享状态。但是两个选项卡具有相同的来源(域名),它们共享cookie。在django中,您通常使用模板标记{% csrf_token %}将csrf标记呈现给html dom,这意味着如果当前标签的csrf标记无效(登录时会发生这种情况),则必须刷新页面才能获得新鲜的令牌。

附加此类事件侦听器的一种方法是:

// check cookie for `logged_in` substring (this only works for insecure cookies. Not http-only)
const isLoggedIn = () => document.cookie.includes('logged_in')

// check cookie for changes when you open this tab
const signInSpy = () => {
  document.visibilitystate === 'visible' &&
    isLoggedIn() &&
    alert('refresh, please')
}

// only attach event handler when not signed in.
document.onvisibilitychange = isLoggedIn() ? null : signInSpy

此示例仅在logged_in不是仅限http的cookie时才有效。有关标签之间进行通信的其他选项,请参阅以下问题: Communication between tabs or windows