JWT токены обработка

JSON Web Token (JWT) используется для безопасной аутентификации и передачи информации между клиентом и сервером. В контексте Vue.js JWT часто применяется для управления сессиями пользователя, авторизации запросов к API и хранения состояния аутентификации.

Структура JWT

JWT состоит из трёх частей, разделённых точками:

  1. Header (заголовок) – содержит информацию о типе токена и алгоритме подписи. Пример:

    {
      "alg": "HS256",
      "typ": "JWT"
    }
  2. Payload (полезная нагрузка) – хранит данные пользователя и дополнительные параметры (claims). Пример:

    {
      "id": "12345",
      "username": "user",
      "exp": 1700000000
    }
  3. Signature (подпись) – обеспечивают целостность токена и проверку подлинности.

Получение и хранение токена в Vue.js

Токен обычно возвращается сервером после успешной аутентификации. В Vue.js его можно хранить в localStorage, sessionStorage или в состоянии Vuex/Pinia.

// Сохранение токена после входа
localStorage.setItem('jwtToken', response.data.token);

// Получение токена
const token = localStorage.getItem('jwtToken');

Отправка токена с запросами

Для авторизации запросов к API токен передается в заголовке Authorization:

import axios from 'axios';

const token = localStorage.getItem('jwtToken');

axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;

axios.get('/api/user')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

Декодирование JWT на клиенте

Для работы с данными, содержащимися в токене, используется библиотека jwt-decode:

import jwt_decode from 'jwt-decode';

const token = localStorage.getItem('jwtToken');
if (token) {
  const decoded = jwt_decode(token);
  console.log(decoded.id, decoded.username, decoded.exp);
}

Это позволяет, например, проверять срок действия токена перед отправкой запросов.

Проверка истечения срока действия токена

Важно не допускать использования просроченных токенов. Сравнение текущего времени с exp позволяет контролировать срок действия:

const token = localStorage.getItem('jwtToken');
if (token) {
  const decoded = jwt_decode(token);
  const currentTime = Math.floor(Date.now() / 1000);
  if (decoded.exp < currentTime) {
    console.warn('Токен истёк');
    localStorage.removeItem('jwtToken');
  }
}

Автоматическое обновление токена

Для долгоживущих сессий сервер может предоставлять refresh token. На клиенте реализуется перехватчик Axios для проверки и обновления токена:

axios.interceptors.response.use(
  response => response,
  async error => {
    if (error.response.status === 401) {
      const refreshToken = localStorage.getItem('refreshToken');
      if (refreshToken) {
        const response = await axios.post('/api/refresh', { token: refreshToken });
        localStorage.setItem('jwtToken', response.data.token);
        error.config.headers['Authorization'] = `Bearer ${response.data.token}`;
        return axios(error.config);
      }
    }
    return Promise.reject(error);
  }
);

Хранение состояния аутентификации

Для реактивного контроля состояния входа пользователя удобнее использовать Vuex или Pinia:

import { defineStore } from 'pinia';

export const useAuthStore = defineStore('auth', {
  state: () => ({
    token: localStorage.getItem('jwtToken') || null,
    user: null,
  }),
  actions: {
    setToken(token) {
      this.token = token;
      localStorage.setItem('jwtToken', token);
    },
    logout() {
      this.token = null;
      this.user = null;
      localStorage.removeItem('jwtToken');
    },
    setUser(user) {
      this.user = user;
    }
  }
});

Защита маршрутов

Для маршрутов, требующих авторизации, используется навигационный guard:

import { useAuthStore } from './stores/auth';
import router from './router';

router.beforeEach((to, from, next) => {
  const authStore = useAuthStore();
  if (to.meta.requiresAuth && !authStore.token) {
    next('/login');
  } else {
    next();
  }
});

Резюме

Обработка JWT в Vue.js включает:

  • Получение и безопасное хранение токена;
  • Добавление токена к HTTP-запросам;
  • Декодирование и проверка срока действия токена;
  • Реактивное управление состоянием аутентификации через Vuex/Pinia;
  • Защиту маршрутов и автоматическое обновление токена при необходимости.

Эффективная интеграция JWT обеспечивает безопасное взаимодействие клиента и сервера и упрощает управление авторизацией внутри SPA на Vue.js.