Проверьте, есть ли у Axios cookie сеанса

Aug 20 2020

Я реализую защиту навигации для своего приложения Vue.js, проверяя, вошел ли пользователь в систему. Я думаю, что лучше всего было бы спросить Axios, есть ли у него файл cookie сеанса или нет. Что-то вроде этого:

router.beforeEach((to, from, next) => {
  if (Vue.axios.hasSessionCookie())
    next()
  else
    next(false);
}

За исключением, конечно, hasSessionCookie()не существует, и я не вижу ничего подобного в документации. Есть ли способ, может быть, каким-то расширением?

Да, я знаю, что могу сохранить статус входа в систему в магазине VueX. Я не думаю, что это хорошая идея, потому что состояние будет сброшено, если пользователь, в своей бесконечной мудрости, обновит страницу и, таким образом, сбросит приложение. Еще одно решение, которое я имею в виду, - это серверная конечная точка, где приложение может «спрашивать», вошли ли оно в систему. Но это тоже довольно неубедительно.

Ответы

2 TamásPolgár Aug 20 2020 at 06:45

Спасибо за все советы. Правильным решением было следующее:

  • VueX хранит статус входа в систему (просто логический флаг), который проверяет система навигации.
  • Когда пользователь входит или выходит из системы, я устанавливаю флаг
  • Когда приложение запускается, я вызываю /checkloginмаршрут на сервере до создания экземпляра Vue. Это просто возвращает код состояния 200 или 401 в зависимости от того, есть у пользователя действительный сеанс или нет. Затем я соответствующим образом установил флаг VueX. Таким образом, пользователь может обновить браузер, но VueX все равно будет знать, вошел он в систему или нет.
  • Плюс я добавил перехватчик Axios для обнаружения ошибки 401. Если он есть, значит, сеанс истек. Затем он устанавливает флаг VueX falseи перенаправляет пользователя на страницу входа.

Я написал статью в своем блоге на Medium с подробностями и отрывками, если кому-то интересно. https://medium.com/developer-rants/session-management-between-express-and-axios

1 Owl Aug 20 2020 at 03:54

Поскольку это серверный файл cookie, вы не можете проверить его на клиентском javascript, вам нужно сделать HTTP-запрос на свой экспресс-сервер, чтобы проверить, существует ли сеанс. Создайте простой маршрут на своем экспресс-сервере следующим образом:

app.get("/checkcookie", function(req,res) {
    if (req.session.yourSessionVariableName) {
        res.status(204).send();
    } else {
        res.status(401).send();
    }
});

Затем проверьте свою навигационную защиту vue:

router.beforeEach(async (to, from, next) => {
  const response = await axios.get("http://yourexpressbackend.com/checkcookie");
  if (response.status === 204)
    next()
  else
    next(false);
}
Akbarkhan Aug 20 2020 at 03:16

Вы идете в правильном направлении, но axios - это HTTP-клиент, и он не имеет ничего общего с куки-файлами и не заботится ни о куки-файлах, ни о хранении ... поэтому вам нужно использовать такой пакет, как vue-куки для установки и получения куки.

generic3892372 Nov 01 2020 at 21:47

Тамаш Полгар, вы задокументировали ту же проблему, что и я с Vue; что делать с логином, если в браузере произошло неожиданное событие и магазин утерян.

Магазин Vue:

Хранилище Vue предназначено для того, чтобы быть удобным местом для SPA для хранения такого флага (вошел в систему или нет), однако хранилище полностью стирается и восстанавливается с каждым экземпляром Vue, что означает новое окно / вкладку браузера, refresh или другое неожиданное событие, вызывающее обновление браузера.

Итак, ваш подход описывает дополнительный внутренний вызов для быстрой проверки статуса, что является законным и работоспособным решением IMO.

Есть еще два потенциальных решения, второе из которых я реализовал в собственном SPA:

Два других решения

1) Не трогайте свой серверный код вообще. Используйте vue-cookies, чтобы клиентский браузер устанавливал cookie после того, как был установлен логин (это будет полностью отделено от cookie только для http, который нужен внутреннему серверу API).

Этот файл cookie должен все еще существовать после обновления браузера. Однако я не использовал (и не пробовал) этот подход, поскольку я не хотел возиться с изменением своего внешнего интерфейса, чтобы проверять локальный файл cookie каждый раз, когда я хочу проверить статус входа.

Код внешнего интерфейса может использовать этот файл cookie, чтобы выяснить, находится ли человек в системе или нет.

2) Другой, отдельный подход состоит в том, чтобы сократить обычную внутреннюю проверку API для аутентификации только для контроллера этого конкретного маршрута , но не для любого другого маршрута.

Вот как могло бы работать «короткое замыкание» на сервере:

В случае метода контроллера этого конкретного маршрута сначала нужно проверить наличие пользователя в запросе, а затем вернуть 200, но со статусом «false» или какой-либо другой переменной, которая также появляется в успешном ответе.

Это нелогично, но это дает клиентскому интерфейсу Axios возможность ухватиться за что-то, кроме стандартного ответа об ошибке.

ПРИМЕЧАНИЕ . Я называю это «коротким замыканием», потому что, если в методе контроллера маршрута внутреннего API-интерфейса много кода, сделав эту проверку ПЕРВОЙ, что она делает, позволит избежать дорогостоящей части вызова.

Этот подход идеально подходит для моих нужд и не требует нового или вторичного вызова API.