How to use NextAuth.js JWT auth with Apollo Client

How to use NextAuth.js JWT auth with Apollo Client

NextAuth.js is a popular authentication library for Next.js that comes with built-in support for dozens of providers (including GitHub, Twitter, Google, and more).

In this guide we will continue where we left off in the guide How to use NextAuth.js as your JWT provider with Grafbase and instead use Apollo Client to send requests.

What's shown below also works with Clerk + Grafbase so you will want to check that if you're looking for an extended User Management solution.

You will want to follow the official documentation if you want to go beyond the basics. Let's begin by installing Apollo Client and its dependencies:

npm install @apollo/client graphql

You will want to create a custom ApolloProviderWrapper component that uses setContext to add your token to the HTTP header authorization.

Create the file components/apollo-provider-wrapper.tsx and add the following:

import { useMemo } from 'react' import { ApolloClient, ApolloProvider, HttpLink, InMemoryCache, from, } from '@apollo/client' import { setContext } from '@apollo/client/link/context' const httpLink = new HttpLink({ uri: process.env.NEXT_PUBLIC_GRAFBASE_API_URL, }) export const ApolloProviderWrapper = ({ children }: PropsWithChildren) => { const client = useMemo(() => { const authMiddleware = setContext(async (operation, { headers }) => { const { token } = await fetch('/api/auth/token').then(res => res.json()) return { headers: { ...headers, authorization: `Bearer ${token}`, }, } }) return new ApolloClient({ link: from([authMiddleware, httpLink]), cache: new InMemoryCache(), }) }, [getToken]) return <ApolloProvider client={client}>{children}</ApolloProvider> }

You'll notice here we are using the environment variable NEXT_PUBLIC_GRAFBASE_API_URL we created in the previous guide.

Now wrap your Next.js application with <ApolloProviderWrapper /> inside of pages/_app.tsx:

import { SessionProvider } from 'next-auth/react' import type { AppProps } from 'next/app' import { ApolloProviderWrapper } from '../components/apollo-provider-wrapper' export default function App({ Component, pageProps: { session, ...pageProps }, }: AppProps) { return ( <SessionProvider session={session}> <ApolloProviderWrapper> <Component {...pageProps} /> </ApolloProviderWrapper> </SessionProvider> ) }

Now all that's left to do is execute a GraphQL operation and the token provided by /api/auth/token will automatically be added to the header of each request.

import { gql, useQuery } from '@apollo/client' const QUERY = gql` { messageCollection(first: 100) { edges { node { id } } } } ` const MyPage = () => { const { data, loading } = useQuery(QUERY) if (loading) return <p>Loading!</p> return <pre>{JSON.stringify(data, null, 2)}</pre> } export default MyPage

That's it! All requests will now be authenticated using the JWT generated by NextAuth.js after you successfully login.

Unauthenticated requests will not be permitted because of the auth rule we configured with Grafbase.

Get Started

Use NextAuth.js with Grafbase as your JWT provider.