Authenticating Vue Apollo Graphql with Laravel Sanctum

If you have been looking for a solution on how authenticating vue apollo graphql with laravel sanctum works with cookies and session, follow along.

This post assumes you are pretty well aware of how Laravel, Vuejs, and both with each other work. So please follow along if you are looking for a solution to authenticate your Vue apollo frontend with Laravel Sanctum guard.

Recently, I have been trying to setup Laravel Sanctum with my new project which uses a frontend of Vue js configured with vue router and apollo to work with graphql request.

Sanctum Middleware

Laravel Sanctum has a great middleware that you can apply on your Laravel backend to authenticate your frontend requests with your cookies.

This middleware directly authenticates a user by session and cookies as it works in the out of the box authentication provided by Laravel.

Vue apollo uses fetch API to make requests to the backend and you can use any fetch options when configuring an httpLink for your vue apollo provider.

I was looking for solutions on the internet but could not find a clear solution on how this can be implemented for this specific scenario, so I am writing this article.

Vue apollo setup

Below is the code snippet to configure standard apollo client for a vue application

import Vue from 'vue';
import VueApollo from 'vue-apollo';

Vue.use(VueApollo);

import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';

const httpLink = createHttpLink({
    uri: '/api/graphql', // The graphql endpoint url
});

// Cache implementation
const cache = new InMemoryCache();

// Create the apollo client
const apolloClient = new ApolloClient({
    link: httpLink,
    cache,
});

// Create the provider for Vue
const apolloProvider = new VueApollo({
    defaultClient: apolloClient,
});

// Initialize vue instance
const app = new Vue({
    el: '#app',
    apolloProvider
 // Register the provider with Vue instance
});

This configuration is useful when you want to create a GraphQL client without authenticating your requests. But if you want to authenticate your requests with Sanctum’s EnsureFrontendRequestsAreStateful middleware, you have to make additional configurations.

By some research, I have been able to make an easy solution to authenticate requests with Sanctum sessions. Please check the below updated code.

import Vue from 'vue';
import VueApollo from 'vue-apollo';

Vue.use(VueApollo);

import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { setContext } from 'apollo-link-context';

// XSRF token is required to make post requests to your Laravel backend
const authLink = setContext((_, { headers }) => {
    let token = RegExp('XSRF-TOKEN[^;]+').exec(document.cookie)
    token = decodeURIComponent(token ? token.toString().replace(/^[^=]+./, '') : '')
    return {
        headers: {
            ...headers,
            'X-XSRF-TOKEN': token,
        },
    };
});

const httpLink = createHttpLink({
    uri: '/api/graphql', // The graphql endpoint url
    credentials: 'same-origin',
});

// Cache implementation
const cache = new InMemoryCache();

// Create the apollo client
const apolloClient = new ApolloClient({
    link: authLink.concat(httpLink),
    cache,
});

// Create the provider for Vue
const apolloProvider = new VueApollo({
    defaultClient: apolloClient,
});

// Initialize vue instance
const app = new Vue({
    el: '#app',
    apolloProvider  // Register the provider with Vue instance
});

These changes will allow your front end to send cookies with your frontend to your backend, so that the backend can verify the user’s authentication by cookie/session.

This feature of Sanctum is very powerful when you want to create an SPA that works with your domain and that without exposing your backend to CSRF requests.

And that’s what needs to be configured to authenticating a vue apollo graphql with laravel sanctum backend.