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. Другие варианты взаимодействия между вкладками см. В следующем вопросе: Связь между вкладками или окнами.