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

Posted

技术标签:

【中文标题】防止 nuxt auth 将授权标头发送到外部 url【英文标题】:Prevent nuxt auth to send authorization header to external url 【发布时间】:2021-07-26 19:11:34 【问题描述】:

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

当用户通过身份验证时,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 模块时,我不确定如何按照 here 或 here 的描述向 axios 实例添加拦截器。

非常感谢任何有关在哪里可以找到帮助的帮助或提示:)

【问题讨论】:

【参考方案1】:

试试下面的

解决方案一,在你的插件文件夹中新建一个 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

【讨论】:

【参考方案2】:

您可以将以下配置传递给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,
  

【讨论】:

感谢您的回答。不幸的是,我不明白您为什么要使用 nuxt-axios 插件以及它的作用 - baseUrlIamundefined 对我来说。但这可能与您的 nuxt-auth.js 有关 - 我不使用自定义 nuxt-auth 插件。这究竟是做什么的?使用它的原因是什么?这对我在nuxt.config.js 中的身份验证配置有何影响? 我改了答案,希望更清楚。

以上是关于防止 nuxt auth 将授权标头发送到外部 url的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Angular 7 将授权标头发送到节点 11/Express 4 服务器

如何将带有数据的http标头发送到rest Api codeigniter?

Nuxt appolo 模块如何发送授权标头?

Nuxt / Apollo - 设置授权标头

Nuxt-auth ..login 网络标头给了我奇怪的路径似乎是我登录页面的语言环境路径

如何解决“将标头发送到客户端后无法设置标头”