Как сохранить вход пользователя в систему с помощью Vuex?

#vue.js #vuex #vue-router #vuejs3

Вопрос:

Я управляю выполнением входа в систему и состоянием входа в систему с помощью Vuex . Это стандартная процедура проведения:

  1. Пользователь отправляет свои регистрационные данные в форме
  2. Форма отправляет Vuex действие для вызова axios API на конечную точку узла/Экспресс /api/login с учетными данными
  3. Ответ от API в случае успеха отправит обратно данные пользователя, которые хранятся в state.user объекте посредством setUser мутации. state.user.isLoggedIn Также установлен флаг true «из».
  4. Маркер доступа JWT отправляется в браузер пользователя и сохраняется в защищенном файле cookie для повторного использования до истечения срока его действия. Если срок его действия истекает, токен обновления используется для создания нового токена доступа JWT.
  5. В заголовке сайта отображается информация для входа пользователя .например, имя

Все вышеперечисленное работает так, как и ожидалось. Однако если пользователь обновит свой браузер, Vuex состояние будет опустошено, и в заголовке сайта больше не будет отображаться информация о пользователе. Чтобы преодолеть это, я сохранил state.user localStorage в браузере сохраненные данные и повторно Vuex заполнил хранилище, используя данные в localStorage обновлении страницы. Если пользователь выходит из системы, localStorage он очищается.

Существует множество маршрутов, требующих проверки того, вошел ли пользователь в систему. Я не могу полагаться на localStorage это, потому что пользователь может манипулировать им. Если пользователь удаляет свои файлы cookie, содержащие JWT, то localStorage они не удаляются, и в заголовке сайта по-прежнему отображается информация об их входе в систему. Поэтому мне нужно выполнить вызов API почти на каждой странице, чтобы проверить, вошел ли пользователь в систему, а если нет localStorage , то также удалить его.

Мой вопрос таков:

  1. Где я могу выполнять проверку входа в систему каждый раз при доступе к странице/представлению? Это происходит всякий раз, когда Vue app монтируется или в пределах vue-router использования beforeEach навигационной защиты?
  2. Если я использую beforeEach in vue-router , приведет ли это к сбою сайта, вызывая API /api/login каждый раз, когда пользователь меняет маршрут? Это нормальная практика — делать это на каждом маршруте?
  3. Существуют ли какие-либо другие альтернативные шаблоны для отслеживания того, вошел ли пользователь в систему или нет?

Комментарии:

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% тяжелой работы.