Как я могу сохранить JWT в файлах cookie с помощью Axios?

Я использую 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);
            });
    });
};

Однако это вообще мешает мне войти в систему, и я получаю сообщение об ошибке «неправильное количество сегментов». Любая идея, почему это не работает?

Вы не можете установить файлы cookie в вызове Ajax. См. мой старый вопрос Как изменить Cookie из вызова Ajax

jcubic 12.02.2019 15:48
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
7
1
11 694
1

Ответы 1

Есть несколько различных вариантов, которые вы можете использовать здесь, чтобы решить проблему, с которой вы столкнулись, а именно найти место для хранения JWT, чтобы вы могли использовать его даже после обновления страницы.

  1. Сохраните 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}`;
  }
})();

Это гарантирует, что пользователь не выйдет из системы при загрузке страницы, если ранее входил в систему.

  1. Сохраните 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 13.02.2019 15:00

@ G.Cox - А, я понял, что назначаю Bearer ${authToken} заголовку авторизации axois при загрузке страницы, когда ясно, что authToken даже не определен в этой анонимной функции. Я исправил свою ошибку выше. Убедитесь, что вы делаете то же самое в своем коде, выполнив что-то вроде let authToken = Cookies.get('token'); перед вашим оператором if/else в вашей анонимной функции.

Pas 13.02.2019 17:54

@ G.Cox - Кроме того, в вашем коде есть еще одна опечатка. Вместо Cookies.setToken('token', authToken) должен быть Cookies.set('token', authToken);

Pas 13.02.2019 18:38

Не храните токены ни в localStorage, ни в sessionStorage, так как они открыты для JavaScript и, следовательно, могут стать легкой мишенью для атак межсайтового скриптинга.

dgarcia 17.12.2020 20:19

Другие вопросы по теме