Nuxt Apollo 带有用于基于会话的身份验证的动态标头

Sud*_*ust 1 cookies session apollo nuxt.js

Apollo 不会动态存储来自查询的标头。

页面/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
      },
    })
  },
},
Run Code Online (Sandbox Code Playgroud)

有没有办法为每个 Apollo 请求设置新的标头值?

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

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

插件/csrf.js

fetch('http://127.0.0.1:8000/api/csrf-cookie', {
  credentials: 'include',
})
Run Code Online (Sandbox Code Playgroud)

现在我设置了一个有效的 Cookie,并希望与 GraphQL Server 通信,但我的标头未在查询中动态设置。有谁知道我该如何解决这个问题?

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

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

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

小智 9

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

第 1 步:创建客户端插件

正如Apollo 模块文档的设置部分所述,我们可以提供一个插件的路径,该插件将定义一个clientConfig

// nuxt.config.js
{
  apollo: {
    clientConfigs: {
      default: '~/plugins/apollo-client.js'
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这个插件应该导出一个接收nuxt 上下文的函数。它应该返回的配置,被传递到vue-cli-plugin-apollocreateApolloClient工具。您无需担心该文件,但它是@nuxtjs/apollo在内部创建客户端的方式。

第 2 步:创建自定义 httpLink

createApolloClient选项中,我们看到我们可以禁用defaultHttpLink并提供我们自己的link. link需要是 Apollo 官方createHttpLink实用程序的输出,其文档可以在这里找到。我们最感兴趣的fetch选项是作为文档状态的选项,是

fetch用于发出请求的兼容 API

这归结为一个函数,它接受urioptions参数并返回一个Promise代表网络交互的 。

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

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

我们将像您在问题中所做的一样提取您的 cookie,然后将其设置为标题。fetch 函数应该是这样的:

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

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

  return fetch(uri, options)
}
Run Code Online (Sandbox Code Playgroud)

把这一切放在一起

最终,您的~/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)
      }
    })
  }
}
Run Code Online (Sandbox Code Playgroud)