【问题标题】:vue-resource interceptor for auth headers用于身份验证标头的 vue-resource 拦截器
【发布时间】:2017-02-01 13:52:32
【问题描述】:

我正在尝试设置一个 Vuejs 前端应用程序(vue-cli webpack 模板)以位于我的 Laravel API 之上。

通过提供正确的身份验证令牌,我可以使用 vue-resource 从 API 获得成功的响应,例如:

methods: {
    getUser () {
      this.$http.get('http://localhost:8000/api/user', 
      {
        headers: {
          'Authorization': 'Bearer eyJ0e.....etc',
          'Accept': 'application/json'
        }
      }).then((response) => {
        this.name = response.data.name
      });
    },

但是,我现在正在尝试设置拦截器,以便为每个请求自动添加用户的身份验证令牌。

根据 vue-resource 自述文件,我正在 main.js 中尝试此操作:

Vue.use(VueResource)

Vue.http.interceptors.push((request, next) => {
  request.headers['Authorization'] = 'Bearer eyJ0e.....etc'
  request.headers['Accept'] = 'application/json'
  next()
})

然后回到我现在的组件中:

this.$http.get('http://localhost:8000/api/user').then((response) => {
    this.name = response.data.name
});

问题:

当我在 get 本身中指定标头时,我得到了成功的响应,但是当我通过 interceptor 传递它们时,我从服务器返回一个 401 Unauthorized。在使用拦截器时如何解决此问题以成功响应?

编辑: 当我使用开发工具查看传出请求时,我看到以下行为:

通过向$http.get 提供标头来发出请求时,我发出一个成功的OPTIONS 请求,然后一个成功的GET 请求,其中Authentication 标头被提供给GET 请求。

但是,当我直接从$http.get 中删除标头并将它们移动到拦截器时,我只发出GET 请求并且GET 不包含Authentication 标头,因此它返回为401 Unauthorized

【问题讨论】:

  • 您是否检查了请求是否包含这些标头?您可以在开发工具的网络部分查看。
  • 这些是跨域调用吗?会不会有 CORS 问题?当您说您看到两个传出请求时,它们都是 GET 请求还是一个 OPTIONS 请求?
  • @Patrick,它们是跨域调用,但是当我直接使用get 时,我得到了成功的响应(这只有在服务器上设置 cors 后才能实现。按秒你提到的事情,第一个请求确实是OPTIONS
  • @DeendayalGarg 我在帖子的“编辑”部分的意思是,在使用拦截器时,传出请求中根本不存在“身份验证”标头。 (但是,它也不存在于不使用拦截器时发送的第一个请求中。所以我不确定问题是否是标头未设置属性,或者第一个请求是否在我们到达之前失败第二)
  • @DeendayalGarg 如果我提供正确的身份验证,我只会获得响应的数据。如果我使用通过http.get 传递身份验证,我会发出一个成功的OPTIONS 请求,然后是一个成功的GET 请求,其中在GET 请求上指定了Authentication 标头(并且提供无效令牌正确失败)。但是,当我引入拦截器来提供身份验证时,似乎OPTIONS 请求没有发出,而是只有一个没有身份验证标头的GET 请求。

标签: vue.js vue-resource


【解决方案1】:

原来我的问题是我在拦截器中设置标头的语法。

应该是这样的:

Vue.use(VueResource)

Vue.http.interceptors.push((request, next) => {
  request.headers.set('Authorization', 'Bearer eyJ0e.....etc')
  request.headers.set('Accept', 'application/json')
  next()
})

当我这样做时:

Vue.use(VueResource)

Vue.http.interceptors.push((request, next) => {
  request.headers['Authorization'] = 'Bearer eyJ0e.....etc'
  request.headers['Accept'] = 'application/json'
  next()
})

【讨论】:

  • 感谢您分享您的答案。你刚刚为我节省了大量时间!
  • 最后一步。这帮助我完成了相同的设置。 +1
  • 我们可以在拦截器中做一些其他的事情吗?就像我想在调用 Cognito Auth API 之前检查我的 AWS Cognito 应用程序中的 Id 令牌到期时间。
  • 如您所见,每个“拦截器”只是一个最终可能调用“next()”的函数。所以是的,你可以在那里做任何你想做的事情。
  • 非常感谢,但我收到错误“VueConstructor”类型上不存在属性“http”
【解决方案2】:

添加此选项:

Vue.http.options.credentials = true;

并将拦截器用于全局方式:

Vue.http.interceptors.push(function(request, next) {

request.headers['Authorization'] = 'Basic abc' //Base64
request.headers['Accept'] = 'application/json'
next()

});

【讨论】:

    猜你喜欢
    • 2020-06-06
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 2018-12-05
    • 1970-01-01
    • 2023-03-22
    • 2015-11-19
    相关资源
    最近更新 更多