防止nuxt auth将授权标头发送到外部url

时间:2021-05-04 12:28:01

标签: vue.js authentication amazon-s3 axios nuxt.js

我想在我使用 nuxt auth 模块的 nuxt 项目中使用 axios 向外部 API 发送 POST 请求。< /p>

当用户通过身份验证时,axios 似乎会自动添加授权标头(这很好,并且通常需要调用我的后端 API)。但是,在调用外部 API 时,标头可能不被接受并导致调用失败。

有什么方法可以指定应该为哪些 URL 添加或排除 auth 标头?

这里是我的nuxt.config中auth和axios模块的配置

  // Axios module configuration
  axios: {
    baseURL: '//localhost:5000',
  },

  // Auth module configuration
  auth: {
    strategies: {
      local: {
        endpoints: {
          login: { url: '/auth/login', method: 'post', propertyName: 'token' },
          logout: { url: '/auth/logout', method: 'delete' },
          user: { url: '/auth/user', method: 'get', propertyName: 'user' },
        },
      },
    },
  }

更多背景: 在我的特定用例中,我想将文件上传到 Amazon S3 存储桶,因此我创建了一个预先签名的上传请求,然后想将文件直接上传到存储桶中。只要用户未通过身份验证,这就能正常工作。

const { data } = await this.$axios.get('/store/upload-request', {
  params: { type: imageFile.type },
})
const { url, fields } = data
const formData = new FormData()
for (const [field, value] of Object.entries(fields)) {
  formData.append(field, value)
}
formData.append('file', imageFile)
await this.$axios.post(url, formData)

我尝试通过请求配置取消设置 Auth 标头:

const config = {
  transformRequest: (data, headers) => {
     delete headers.common.Authorization
  }
}
await this.$axios.post(url, formData, config)

这似乎阻止添加所有与 formData 相关的标题。此外,通过 headers 属性或 transformRequest 函数在配置中设置任何标头都不起作用,这再次导致对外部 API 的调用明显失败(请求将在没有任何这些的情况下发送特定的标题)。

当我使用 nuxt axios 模块时,我不确定如何将拦截器添加到 axios 实例中,如 herehere 所述。

非常感谢您提供有关何处寻求帮助的任何帮助或提示:)

2 个答案:

答案 0 :(得分:0)

您可以将以下配置传递给 nuxt-auth。请注意,那些 plugins 与根配置无关,而是与 nuxt-auth 包有关。

nuxt.config.js

auth: {
  redirect: {
    login: '/login',
    home: '/',
    logout: '/login',
    callback: false,
  },
  strategies: {
    ...
  },
  plugins: ['~/plugins/config-file-for-nuxt-auth.js'],
},

然后,创建一个插件文件作为 @nuxt/auth 的配置(当然你需要安装 @nuxt/axios。 PS:在这个文件中,以exampleBaseUrlForAxios为例,在使用@nuxt/auth时设置axios调用的变量。

config-file-for-nuxt-auth.js

export default ({ $axios, $config: { exampleBaseUrlForAxios } }) => {
  $axios.defaults.baseURL = exampleBaseUrlForAxios
  // I guess that any usual axios configuration can be done here
}

这是本 article 中所解释的推荐的处理方式。基本上,您可以在使用它时将运行时变量传递给您的项目。因此,这里我们传递了一个 EXAMPLE_BASE_URL_FOR_AXIOS 变量(位于 .env 中)并将其重命名为我们希望在项目中使用的名称。

nuxt.config.js

export default {
  publicRuntimeConfig: {
    exampleBaseUrlForAxios: process.env.EXAMPLE_BASE_URL_FOR_AXIOS,
  }
}

答案 1 :(得分:0)

试试下面的方法

方案一,在你的plugins文件夹中新建一个axios实例:

export default function ({ $axios }, inject) {
    // Create a custom axios instance
    const api = $axios.create({
        headers: {
            // headers you need
        }
    })
    // Inject to context as $api
    inject('api', api)
}

在nuxt.config.js中声明这个插件,然后你就可以发送你的请求了:

this.$api.$put(...)

方案二,在plugins/axios.js中将axios声明为插件,并根据请求url设置听者:

export default function({ $axios, redirect, app }) {
    const apiS3BaseUrl = // Your s3 base url here
    $axios.onRequest(config => {
        if (config.url.includes(apiS3BaseUrl) {
            setToken(false)
            // Or delete $axios.defaults.headers.common['Authorization']
        } else {
            // Your current axios config here
        }
    });
}

在 nuxt.config.js 中声明这个插件

我个人使用第一种解决方案,如果有一天 s3 url 发生变化也没关系。

这是doc