django обнаруживает логин пользователя в другой вкладке

Есть ли в django что если у пользователя есть две открытые вкладки, обе вышли из системы, а затем входят в одну вкладку, скажите, что он вошел в другую вкладку? Я имею в виду что-то вроде GitHub, который говорит вам, что вы вошли в систему, пожалуйста, обновите страницу.

Проблема в том, что если я войду в одну вкладку, а затем во вторую, я получу csrf token missing incorrect.

2 ответа

Ты получаешь csrf token missing incorrect. потому что, когда пользователь повторно регистрируется, сервер генерирует новый токен csrf для cookie. Файл cookie сохраняется в том же домене. И когда вы пытаетесь сделать что-то на текущей странице, запрос не выполняется, потому что CSRF в вашем <form> отличается от cookie, который был изменен. Вот почему GitHub обновляет страницу (вместо того, чтобы продолжать делать запросы от нее). Таким образом, сервер вернет в вашу форму новый csrf в формате html.

Редактировать:

Рассмотрим следующие варианты:

  • Если ваш файл cookie не только для чтения:. Задавать setInterval где вы проверяете сеанс, какой пользователь загрузил страницу и текущий сеанс из cookie.
  • Рендеринг 4 первых символов тоже страница и сохранить его в переменной. Установите эту переменную при загрузке страницы. И с каждым запросом передавайте переменную с заголовками. Добавьте промежуточное ПО, которое проверяет, соответствуют ли первые 4 символа в заголовках первые 4 символа из cookie, и не сообщает ли клиенту обновить страницу.
  • Если вы хотите автоматически обнаружить ваше дело, вам нужно часто спамить сервер и спрашивать, изменился ли сеанс. С клиента вы можете отправить старую сессию и новую (если сессия доступна только для чтения, вы можете отправить как несколько первых символов с сервера).

Я не знаю точно, как Github это делает. Но одна возможность заключается в использовании visibilitychange обработчик события. Это сработает при переключении вкладок. Обработчик событий может проверять файлы cookie для текущего сайта и определять, заходил ли кто-либо на другую вкладку.

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

Обычно вкладки не имеют общего состояния. Но две вкладки имеют одинаковое происхождение (доменное имя), они совместно используют куки. В django вы обычно выводите токен csrf в html dom с тегом шаблона {% csrf_token %}Это означает, что если токен текущей вкладки 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 не является файлом cookie только для http. Другие варианты взаимодействия между вкладками см. В следующем вопросе: Связь между вкладками или окнами.

Другие вопросы по тегам