具有动态 headers 的 Nuxt Apollo,用于基于 session 的身份验证

Nuxt Apollo with dynamic headers for a session based authentication

Apollo 没有动态存储来自查询的 header。

pages/index.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 请求设置新的 header 值?

我有一个单独的前端和后端。对于前端,我将 Nuxt.js 与 Apollo 一起使用。我想与我的服务器进行基于 session 的通信。出于这个原因,我需要在每个请求中发送 CSRF-Token。

现在的问题是:第一次加载页面时,浏览器上没有设置 Cookie。我在每次初始化我的 Nuxt 应用程序时都会执行 GET-Request。

plugins/csrf.js

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

现在我这边设置了一个有效的 Cookie,想与 GraphQL 服务器通信,但我的 header 没有在查询中动态设置。有谁知道我该如何解决这个问题?

我的 Laravel 后端现在抛出 419 令牌不匹配异常,因为我没有在请求中发送 CSRF-Token。

Link 到存储库:https://github.com/SuddenlyRust/session-based-auth

[已解决] 工作解决方案:https://github.com/SuddenlyRust/session-based-auth/commit/de8fb9c18b00e58655f154f8d0c95a677d9b685b 感谢 Nuxt Apollo discord 频道 kofh 的帮助

为了实现这一点,我们需要在每次 fetch 发生时访问获取 运行 的代码。此代码位于 Apollo 客户端的 HttpLink 中。虽然 @nuxtjs/apollo 模块为我们提供了很多选项,但我们无法在如此高的级别上进行配置。

第 1 步:创建客户端插件

如 Apollo 模块文档的 setup section 所述,我们可以提供一个插件路径,该插件将定义 clientConfig:

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

这个插件应该导出一个接收 nuxt context. It should return the configuration to be passed to the vue-cli-plugin-apollo's createApolloClient utility 的函数。您无需担心该文件,但它是 @nuxtjs/apollo 在内部创建客户端的方式。

第 2 步:创建自定义 httpLink

createApolloClient 的选项中,我们看到我们可以禁用 defaultHttpLink 而提供我们自己的 linklink 需要是 Apollo 的官方 createHttpLink 实用程序的输出,可以找到其文档 here。我们最感兴趣的选项是 fetch 选项,正如文档所述,它是

a fetch compatible API for making a request

这归结为一个函数,该函数采用 urioptions 参数和 returns 表示网络交互的 Promise

第 3 步:创建自定义 fetch 方法

如上所述,我们需要一个接受 urioptions 以及 returns 承诺的函数。此函数将是标准 fetch 方法的简单传递(您可能需要将 isomorphic-fetch 添加到您的依赖项并根据您的设置将其导入此处)。

我们将像您在问题中所做的那样提取您的 cookie,然后将其设置为 header。提取函数应如下所示:

(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)
      }
    })
  }
}