#vue.js #vuex #vue-router #vuejs3
Вопрос:
Я управляю выполнением входа в систему и состоянием входа в систему с помощью Vuex
. Это стандартная процедура проведения:
- Пользователь отправляет свои регистрационные данные в форме
- Форма отправляет
Vuex
действие для вызоваaxios
API на конечную точку узла/Экспресс/api/login
с учетными данными - Ответ от API в случае успеха отправит обратно данные пользователя, которые хранятся в
state.user
объекте посредствомsetUser
мутации.state.user.isLoggedIn
Также установлен флагtrue
«из». - Маркер доступа JWT отправляется в браузер пользователя и сохраняется в защищенном файле cookie для повторного использования до истечения срока его действия. Если срок его действия истекает, токен обновления используется для создания нового токена доступа JWT.
- В заголовке сайта отображается информация для входа пользователя .например, имя
Все вышеперечисленное работает так, как и ожидалось. Однако если пользователь обновит свой браузер, Vuex
состояние будет опустошено, и в заголовке сайта больше не будет отображаться информация о пользователе. Чтобы преодолеть это, я сохранил state.user
localStorage
в браузере сохраненные данные и повторно Vuex
заполнил хранилище, используя данные в localStorage
обновлении страницы. Если пользователь выходит из системы, localStorage
он очищается.
Существует множество маршрутов, требующих проверки того, вошел ли пользователь в систему. Я не могу полагаться на localStorage
это, потому что пользователь может манипулировать им. Если пользователь удаляет свои файлы cookie, содержащие JWT, то localStorage
они не удаляются, и в заголовке сайта по-прежнему отображается информация об их входе в систему. Поэтому мне нужно выполнить вызов API почти на каждой странице, чтобы проверить, вошел ли пользователь в систему, а если нет localStorage
, то также удалить его.
Мой вопрос таков:
- Где я могу выполнять проверку входа в систему каждый раз при доступе к странице/представлению? Это происходит всякий раз, когда Vue
app
монтируется или в пределахvue-router
использованияbeforeEach
навигационной защиты? - Если я использую
beforeEach
invue-router
, приведет ли это к сбою сайта, вызывая API/api/login
каждый раз, когда пользователь меняет маршрут? Это нормальная практика — делать это на каждом маршруте? - Существуют ли какие-либо другие альтернативные шаблоны для отслеживания того, вошел ли пользователь в систему или нет?
Комментарии:
1. Вы знаете… снова и снова, это причины, по которым я в конечном итоге всегда возвращаюсь к PHP для управления сеансами. Это так просто, но эти библиотеки JavaScript, похоже, не реализуют это. когда-либо.
Ответ №1:
Решения приложений, подобные этому, как правило, субъективны, потому что каждое приложение отличается от других, с разными требованиями и разной архитектурой. Похоже, это одностраничное приложение, так что я начну с этого.
Во — первых, тот факт, что ваш JWT настроен и работает отлично-это может быть очень тяжелая работа, так что гордитесь тем, что вы зашли так далеко.
Если в вашем приложении есть определенные страницы, которые доступны без предварительного входа в систему (например, страница входа в систему или страница с отказом в доступе и т. Д.), Вам также следует учитывать это при разработке. В этом случае beforeEach
защита маршрута-идеальное решение для предотвращения загрузки маршрута или для поимки тех пользователей, которые не вошли в систему, прежде чем они попытаются запросить контент, который, скорее всего, просто выдаст им ошибку.
Вероятно, вам не следует вызывать API на сервер каждый раз, когда пользователь переходит на новую страницу. Это, вероятно, было бы немного медленно. Поскольку ваше приложение использует JWT в комплекте с токенами обновления, вы должны иметь возможность полагаться на них, чтобы, если пользователь вошел в систему, он продолжал входить в систему до тех пор, пока не закроет браузер и не уйдет.
Вот почему вы не должны использовать localStorage. Когда вкладка закрывается или даже после перезагрузки, пользователь по-прежнему будет отображаться как вошедший в систему. Вместо использования localStorage
используйте sessionStorage
полезную ссылку MDN.
Теперь событие входа в систему для извлечения user
объекта должно происходить только один раз для каждой вкладки браузера, но оставаться активным во время посещения.
Интересно, почему вы просто не запрашиваете новый user
объект с сервера при обновлении браузера. Нет ничего странного в принудительной повторной проверке сервера на предмет полной загрузки страницы. Это означало бы, что вам не придется использовать что-либо за пределами Vuex для хранения состояния пользователя
Далее, есть ли способ проверить действительность их JWT во время навигационного события? В зависимости от того, как вы обрабатываете JWT, у вас может быть доступ к нему, и вы, возможно, сможете его декодировать (например, через oidc-client-js
библиотеку), и таким образом определите для себя, истек ли срок действия токена. Однако, если срок действия токена истек, ваша система обновления токенов может просто обновить его и не сообщать вам об этом.
Вы также можете просматривать свои HTTP-запросы и искать 401 или 403 ответа (однако ваш сервер обрабатывает пользователей, вышедших из системы), и направлять пользователя обратно на экран входа в систему, если вы видите один из них. Вы можете использовать глобальные перехватчики Axios, чтобы перехватить их, или сделать это самостоятельно, если вы централизовали местоположение, из которого вызывается Axios.
В целом, вы на своем пути и явно хорошо разбираетесь в этом. Большой прогресс до сих пор, выполнив, вероятно, уже 90% тяжелой работы.