Vue-Apollo and Laravel Authentication Issue

Onur Köse
2 min readMar 12, 2020

This one is really short;

I am currently working on a project which requires authentication to its API server. API server built up on Laravel and uses Airlock (can be used Passport it doesn’t matter) for API authentication.

To authenticate the GraphQL requests on API server, we use attaching access token to headers option, like this;

import { ApolloClient } from 'apollo-client'
import { from } from 'apollo-link'
import { HttpLink } from 'apollo-link-http'
import { onError } from 'apollo-link-error'
const getHeaders = () => {
const headers = {}
const token = Vue.prototype.$token // comes from auth plugin, may also derived from session storage
if (token) {
headers.Authorization = `Bearer ${token}`
}

return headers
}
const apolloClient = new ApolloClient({
link: from([
onError(errorHandler => {
console.warn(errorHandler)
}),
new HttpLink({
uri: `http://localhost/graphql`,
headers: getHeaders()
})
]),
cache, // comes from InMemoryCache
connectToDevTools: true
})

The issue with this is, ApolloLinkHttp comes with two default headers:

/node_modules/apollo-link-http-common/lib/bundle.cjs.jsvar defaultHeaders = {
accept: '*/*',
'content-type': 'application/json',
};

ContentType is totally fine to be here but accept key is a big no no for Laravel. Laravel tends to redirect user to “login” of its web ui, if detects a generic “*/*” setting on accept header. Therefore, if your token is expired and if you try to catch it in your interceptors, you won’t be able to do that.

To correct this, change the getHeaders function like this:

const getHeaders = () => {
const headers = {}
const token = Vue.prototype.$token // comes from auth plugin
if (token) {
headers.Authorization = `Bearer ${token}`
}
headers.accept = 'application/json' return headers
}

Another trick here, don’t write here (like me) “headers.Accept” because you’ll end up with two headers on your request, and of course Laravel still be redirecting user to login route:

accept: */*
Accept: application/json

Laravel should now return a nice JSON with a 401 status code and you may intercept it as you wish:

{message: “Unauthenticated.”}

--

--