13

I am trying to set up a Vuejs fronted application (vue-cli webpack template) to sit on top of my Laravel API.

I am able to get a successful response from the API with vue-resource by providing the correct auth token, for example:

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
      });
    },

However, I am now trying to set up interceptors so that the user's auth token will automatically be added for each request.

Based on the vue-resource readme I am trying this in my main.js:

Vue.use(VueResource)

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

And then back in my component I now just have:

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

Problem:

When I specify the headers in the get itself, I get a successful response, but when I pass them through the interceptor I get back a 401 Unauthorized from the server. How can I fix this to respond successfully while using the interceptor?

Edit: When I use dev-tools to view the outgoing requests I see the following behavior:

When making the request by supplying the headers to $http.get, I make a successful OPTIONS request and then a successful GET request with the Authentication header being supplied to the GET request.

However, when I remove the headers from the $http.get directly and move them to the interceptor, I only make a GET request and the GET does not contain the Authentication header, thus it comes back as a 401 Unauthorized.

tam5
  • 3,197
  • 5
  • 24
  • 45
  • did you check if the request has those headers? you can check that in Network section of dev tools. – Deendayal Garg Sep 23 '16 at 16:44
  • Are these cross-domain calls? Could there be a CORS issue? When you say you see two outgoing requests, are they both `GET` requests or is one an `OPTIONS` request? – PatrickSteele Sep 23 '16 at 16:48
  • @Patrick, they are cross-domain calls, but I am getting a successful response when I use `get` directly (and this was only achieved after setting up cors on the server. As per the second thing you mentioned, the first request is indeed an `OPTIONS` – tam5 Sep 23 '16 at 16:50
  • 1
    @DeendayalGarg what i mean in the 'edit' section of the post is that while using the interceptor, the 'Authentication' header is not present on the outgoing request at all. (However, it is also not present on the FIRST request sent when not using the interceptor. so I am not sure if the issue is that the headers are not being set property OR if maybe the first request is failing before we even get to the second) – tam5 Sep 23 '16 at 16:56
  • that shouldn't happen. if there are no auth headers without the interceptor then it means the server really don't need any auth header since you are getting the response. – Deendayal Garg Sep 23 '16 at 16:59
  • 1
    @DeendayalGarg I only get the data of the response if I provide the correct authentication. If I use the pass the auth through `http.get` I make a successful `OPTIONS` request and then a successful `GET` request where the Authentication header is specified on the `GET` request (and providing an invalid token fails correctly). However, when I introduce the interceptor to provide the authentication, it seems the `OPTIONS` request doesn't go out, and instead only a `GET` request without the authentication header. – tam5 Sep 23 '16 at 17:05

2 Answers2

35

It turns out my problem was the syntax for which I was setting the headers in the interceptor.

It should be like this:

Vue.use(VueResource)

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

While I was doing this:

Vue.use(VueResource)

Vue.http.interceptors.push((request, next) => {
  request.headers['Authorization'] = 'Bearer eyJ0e.....etc'
  request.headers['Accept'] = 'application/json'
  next()
})
tam5
  • 3,197
  • 5
  • 24
  • 45
0

Add this option:

Vue.http.options.credentials = true;

And use the interceptors for global way:

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

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

});

Pardeep Jain
  • 84,110
  • 37
  • 165
  • 215
Satu
  • 68
  • 1
  • 2
  • 8