Headers Token передавать в каждой запросе?

Добрый день дорогие друзья Моя задача - передавать токен в в каждом запросе Ну не передавать его вручную (думаю понятно написал =) )

Для этого я написал такой код в main.js

Vue.prototype.$http.interceptors.request.use(
    (config) => {
        const token = localStorage.getItem('token')

        if (token) {
            config.headers.Authorization = token
        }
        return config
    },
    (error => {
        return Promise.reject(error)
    })
)

Вот мой store

Как мне его переделать

const token = localStorage.getItem('retriewToken')

export default new Vuex.Store({
  state: {
    token: token || null
  },

  mutations: {
    retriewToken(state, token) { // мутация токена
      state.token = token
      state.isAuth = Boolean(token)
    }
  },

  actions: {
    retriewToken(context, credentials) {
      return new Promise((resolve, reject) => { //получаем токен по email/pass
        axios.post('web/login', {
          phone: credentials.phone,
          code: credentials.code
        })
          .then(response => {
          const token = response.data.result.token //беру токен - ключ
          localStorage.setItem('retriewToken', token)
          context.commit('retriewToken', token)
          resolve(response)
        })
      })
    }
  }
})

Пример запроса

created() {
  const headers = {
    'Content-type': 'application/json',
    'Authorization': `Bearer ${this.token}`, //передача токена
  }
  axios.get('/mobile/user', {
    headers: headers
  })
    .then((response) => {
    this.client = response.data.result
    console.log("CLEINT data: ",this.client);
    this.clientInput = {...response.data.result}
  })
    .catch(e => {
    if (e.response.status === 401) {
      // alert("Авторизуйся ", e);
      localStorage.removeItem('retriewToken')
      this.$router.push({name: 'Home'})
    }
  });
}

Как правильно организовать headers, реактивно и по дефолту передавать headers token


Ответы (1 шт):

Автор решения: Vasiliy Rusin

Я бы порекомендовал добавить Вам дополнительный уровень абстракции для Ваших запросов, а именно Service'ы. Данное изображение хорошо демонстрирует порядок движения ваших данных. Здесь Web API - это API вашего backend'а. Service Layer - это ваши сервисы и Storаge Layer - это VueX.

Web API -> Service Layer -> Storage Layer

Для чего нужна эта абстракция?

Она позволяет вашему приложению не знать о том откуда приходят данные, магические ворота из-за которых просто приходят данные. Никаких клиент-серверных отношений.

Как создаются сервисы?

Для начала мы можем создать базовый файл Service.js в отдельной папочке service в src.

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

Наш файл Service.js будет содержать базовый класс сервиса.

Для простоты, я использую тут axios но, Вы можете написать свою абстракцию, для клиента запросов и не беспокоиться о том, какая библиотека используется в Вашем случае.

import Axios from "axios";
  
export default class Service {
    static http = Axios;
}

Теперь мы можем написать свой первый сервис. И это будет сервис для аутентификации.

Создадим файл AuthenticationService.js.

import Service from "@/services/Service.js";

export class AuthenticationService extends Service {
  static login (login, password) {
    return this.http.post("", { login, password });
  }
}

Как это использовать?

Если Вы правильно пишите свое приложение, то все ваши запросы происходят исключительно через Vuex, а именно через экшены (actions). Именно их мы и рассмотрим. И так, представим что у нас есть именованный модуль authentication.

Тогда его actions будут выглядеть так:

actions: {
  async LOGIN ({ commit }, payload: { login, password }) {
    try {
      const { data } = await AuthenticationService.login(login, password);

      commit("SET_AUTHENTICATION", data);
    } catch (e) {
      throw new Error(e);
    }
  }
}

Много кода, не много разницы. Почему бы мне просто не делать запросы прямо в экшене?

Вероятнее всего вы делаете одни и те же запросы в разных местах в вашем проекте. Представьте что вывод этого метода внезапно изменился. Он отдает все те же данные просто иначе, например появилась дополнительная вложенность или изменилось название, например login изменился на loginOrEmail.

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

У нас есть приложение Pokédex. У бэкенда есть метод getPokemons он реализует пагинацию и фильтр relations, который принимает id покемона и возвращает все формы развития этого покемона.

Один и тот же метод используется для получения всех покемонов, получения одного покемона, а так же при фильтрации всех покемонов по покемону.

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

→ Ссылка