Я использую JWT в своем приложении React и Axios для обработки вызовов API. Я ищу способ сохранить токен в файлах cookie, чтобы меня не перенаправляли для входа в систему каждый раз при обновлении браузера.
Вот моя настройка для Axios и мой вызов для входа:
let authToken = null;
const axios = axiosAPI.create({
baseURL: baseURL
});
// User login
export const loginUser = (data) => {
return new Promise((resolve, reject) => {
axios.post(`${baseURL}/jwt-auth/v1/token`, data)
.then((res) => {
authToken = res.data.token;
// Adds the token to the header
axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;
resolve(res.data);
})
.catch((error) => {
reject(error);
});
});
};
Я не уверен, где я должен установить файл cookie и как его установить?
Обновлено:
Я переписал свой код с помощью js-cookie, чтобы он выглядел как комментарий.
import axiosAPI from 'axios';
import Cookies from 'js-cookie';
let authToken = null;
const axios = axiosAPI.create({
baseURL: `${baseURL}`
});
// Check if user is logged in.
(function () {
if (Cookies.get('token') === null) {
// This means that there's no JWT and no user is logged in.
axios.defaults.headers.common.Authorization = null;
} else {
// This means that there's a JWT so someone must be logged in.
axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;
}
}());
// User login
export const loginUser = (data) => {
return new Promise((resolve, reject) => {
axios.post(`${baseURL}/jwt-auth/v1/token`, data)
.then((res) => {
authToken = res.data.token;
Cookies.setToken('token', authToken);
// Adds the token to the header
axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;
resolve(res.data);
})
.catch((error) => {
reject(error);
});
});
};
Однако это вообще мешает мне войти в систему, и я получаю сообщение об ошибке «неправильное количество сегментов». Любая идея, почему это не работает?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Есть несколько различных вариантов, которые вы можете использовать здесь, чтобы решить проблему, с которой вы столкнулись, а именно найти место для хранения JWT, чтобы вы могли использовать его даже после обновления страницы.
Сохраните JWT в местное хранилище или сеансХранилище в обратном вызове axios.post, чтобы у вас был доступ к нему даже после обновления страницы. Чтобы узнать, какое хранилище лучше всего подходит для вашего приложения, см. это.
Короче говоря, значения, хранящиеся в местное хранилище, будут сохраняться до тех пор, пока вы не удалите их явным образом (вы можете сделать это с помощью кода JS). Кроме того, любые вкладки, которые вы открываете в своем браузере для этого домена, будут иметь доступ к этому (очень полезно, если вы хотите войти в систему с новыми вкладками). С другой стороны, значения, хранящиеся в сеансХранилище, существуют только до тех пор, пока вкладка не будет закрыта. Они также не могут быть разделены между вкладками.
Использовать это так же просто, как:localStorage.setItem("JWT", authToken); или sessionStorage.setItem("JWT", authToken); в вашем обратном вызове после вашего authToken = res.data.token;
Итак, теперь, когда у вас есть место, где вы сохранили JWT, все, что вам нужно сделать, это убедиться, что JWT существует в хранилище, когда ваше приложение инициализируется при загрузке страницы (или обновлении). Вот базовый пример использования localStorage:
// This should be one of the first things that run on your app.
const axios = axiosAPI.create({
baseURL: baseURL
});
// Check if user is logged in.
(function() {
let authToken = localStorage.getItem("JWT");
if (authToken === null) {
// This means that there ISN'T JWT and no user is logged in.
axios.defaults.headers.common.Authorization = null;
} else {
// This means that there IS a JWT so someone must be logged in.
axios.defaults.headers.common.Authorization = `Bearer ${authToken}`;
}
})();
Это гарантирует, что пользователь не выйдет из системы при загрузке страницы, если ранее входил в систему.
Сохраните JWT в файле куки на стороне клиента. Здесь файл cookie используется в качестве механизма хранения, поскольку вы на самом деле не работаете с файлами cookie на стороне сервера, учитывая, что ваша аутентификация построена вокруг JWT. Вы можете следовать тому же шаблону кода, что и выше, но вместо этого будете использовать document.cookie = "key=value" для установки файла cookie и document.cookie для просмотра файлов cookie все.
Этот второй способ менее распространен, потому что он заставляет вас выполнять много ручного труда, например анализировать все файлы cookie и устанавливать правильный атрибут cookie path, чтобы файл cookie отправлялся только для необходимых конечных точек (в противном случае вы просто создает ненужные накладные расходы). Если вы воспользуетесь этой опцией, прочтите это, чтобы помочь вам создать файл cookie в соответствии с вашими потребностями. Вы также можете использовать вспомогательную JS-библиотеку, например js-куки, чтобы управлять файлами cookie на стороне клиента.
Кроме того, я бы прочитал https://stackoverflow.com/a/40376819/11048825, чтобы углубиться в эти два варианта и понять плюсы и минусы, связанные с каждым из них.
Пытался использовать ваш код и использовать js-cookie для установки и получения файлов cookie. Я редактирую исходный пост, чтобы показать мой новый код. Любая идея, почему это не работает?
@ G.Cox - А, я понял, что назначаю Bearer ${authToken} заголовку авторизации axois при загрузке страницы, когда ясно, что authToken даже не определен в этой анонимной функции. Я исправил свою ошибку выше. Убедитесь, что вы делаете то же самое в своем коде, выполнив что-то вроде let authToken = Cookies.get('token'); перед вашим оператором if/else в вашей анонимной функции.
@ G.Cox - Кроме того, в вашем коде есть еще одна опечатка. Вместо Cookies.setToken('token', authToken) должен быть Cookies.set('token', authToken);
Не храните токены ни в localStorage, ни в sessionStorage, так как они открыты для JavaScript и, следовательно, могут стать легкой мишенью для атак межсайтового скриптинга.
Вы не можете установить файлы cookie в вызове Ajax. См. мой старый вопрос Как изменить Cookie из вызова Ajax