Nuxt Apollo с динамическими c заголовками для аутентификации на основе сеанса - PullRequest
0 голосов
/ 22 марта 2020

Apollo не сохраняет заголовок из запроса динамически.

страницы / индекс. vue

methods: {
  fetchCars() {
    const token = Cookies.get('XSRF-TOKEN')

    console.log(token) // ? Token is shown in console

    this.$apollo.query({
      query: gql`
        query {
          cars {
            uuid
            name
          }
        }
      `,
      headers: {
        'X-XSRF-TOKEN': token, // ⭕ Fetch without header
      },
    })
  },
},

Есть ли способ установить заголовок новое значение для каждого запроса Apollo?

У меня есть отдельный Frontend и Backend. Для интерфейса я использую Nuxt. js с Apollo. Я хочу иметь сеанс связи с моим сервером. По этой причине мне нужно отправлять CSRF-токен с каждым запросом.

Теперь проблема: при первой загрузке страницы в браузере не установлен Cook ie. Я делаю GET-запрос на каждую инициализацию моего приложения Nuxt.

plugins / csrf. js

fetch('http://127.0.0.1:8000/api/csrf-cookie', {
  credentials: 'include',
})

Теперь у меня есть действительный Cook ie установить на моей стороне и хочу общаться с сервером GraphQL, но мой заголовок не устанавливается динамически в запросе. Кто-нибудь знает, как я могу решить эту проблему?

Мой Laravel Backend теперь генерирует исключение 419 несоответствия токенов, потому что я не отправил токен CSRF с моим запросом.

Ссылка на хранилище: https://github.com/SuddenlyRust/session-based-auth

[решено] Рабочий раствор: https://github.com/SuddenlyRust/session-based-auth/commit/de8fb9c18b00e58655f154f8d0c95a677d9b685b Благодаря помощи kofh в Nuxt Apollo канал раздора ?

1 Ответ

2 голосов
/ 22 марта 2020

Чтобы выполнить sh, нам нужен доступ к коду, который запускается каждый раз, когда происходит fetch. Этот код находится внутри HttpLink вашего клиента Apollo. В то время как модуль @nuxtjs/apollo дает нам много опций, мы не можем настроить это на таком высоком уровне.

Шаг 1. Создание клиентского плагина

Как отмечено в разделе установки документации модуля Apollo, мы можем указать путь к плагину, который определит clientConfig:

// nuxt.config.js
{
  apollo: {
    clientConfigs: {
      default: '~/plugins/apollo-client.js'
    }
  }
}

Этот плагин должен экспортировать функцию, которая получает контекст nuxt . Он должен вернуть конфигурацию, которая будет передана утилите vue-cli-plugin-apollo createApolloClient . Вам не нужно беспокоиться об этом файле, но именно так @nuxtjs/apollo создает клиента внутри.

Шаг 2: Создание пользовательских httpLink

В опциях createApolloClient мы видим, что мы можем отключить defaultHttpLink и вместо этого предоставить наш собственный link. link должен быть выходом официальной утилиты Apollo createHttpLink, документы для которой можно найти здесь . Опция, которая нас больше всего интересует, это опция fetch, которая в качестве состояния документов представляет собой

a fetch совместимый API для выполнения запроса

This сводится к значению функции, которая принимает параметры uri и options и возвращает Promise, который представляет сетевое взаимодействие.

Шаг 3. Создание пользовательского метода fetch

Как указано выше, нам нужна функция, которая принимает uri и options и возвращает обещание. Эта функция будет простым переходом к стандартному методу fetch (вам может понадобиться добавить isomorphic-fetch к вашим зависимостям и импортировать его здесь в зависимости от ваших настроек).

Мы извлечем вашего повара ie так же, как вы делали в своем вопросе, а затем установите его в качестве заголовка. Функция выборки должна выглядеть следующим образом:

(uri, options) => {
  const token = Cookies.get('XSRF-TOKEN')

  options.headers['X-XSRF-TOKEN'] = token

  return fetch(uri, options)
}

Собрать все вместе

В конечном итоге ваш файл ~/plugins/apollo-client.js должен выглядеть примерно так:

import { createHttpLink } from 'apollo-link-http'
import fetch from 'isomorphic-fetch'

export default function(context) {
  return {
    defaultHttpLink: false,
    link: createHttpLink({
      uri: '/graphql',
      credentials: 'include',
      fetch: (uri, options) => {
        const token = Cookies.get('XSRF-TOKEN')

        options.headers['X-XSRF-TOKEN'] = token

        return fetch(uri, options)
      }
    })
  }
}
...