Skip to content

Instantly share code, notes, and snippets.

@taro-28
Last active July 28, 2024 20:40
Show Gist options
  • Save taro-28/c74c7a93f1400055e8929d9230defe37 to your computer and use it in GitHub Desktop.
Save taro-28/c74c7a93f1400055e8929d9230defe37 to your computer and use it in GitHub Desktop.
Apollo Client with NextAuth

Apollo Client with NextAuth

How to use NextAuth access token in Apollo Client request headers.

AuthApolloProvider.tsx

import {
  ApolloClient,
  ApolloProvider,
  InMemoryCache,
  createHttpLink,
  from,
} from "@apollo/client";
import { setContext } from "@apollo/client/link/context";
import { useSession } from "next-auth/react";
import { useLayoutEffect } from "react";

const authLink = setContext((_, { headers, accessToken }) => ({
  headers: {
    ...headers,
    authorization: accessToken ? `Bearer ${accessToken}` : "",
  },
}));

const httpLink = createHttpLink({
  uri: "https://example.com/",
});

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache(),
});

const AuthApolloProvider = ({ children }: { children: ReactNode }) => {
  const { data } = useSession();

  // I want to use useEffect here because this effect is not for layout.
  // But defaultContext is not reflected for first query of useQuery.
  useLayoutEffect(() => {
    if (!data) return;
    client.defaultContext.accessToken = data.accessToken;
  }, [data]);

  return <ApolloProvider client={client}>{children}</ApolloProvider>;
};

Supplement

[...nextauth].ts

import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

export default NextAuth({
  providers: [
    CredentialsProvider({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" },
      },
      authorize: (credentials) => {
        if (!credentials) return null;
        return { id: "1", name: "taro", email: "[email protected]" };;
      },
    }),
  ],
  session: { strategy: "jwt" },
  callbacks: {
    jwt: ({ token, user }) => {
      if (user) {
        token.id = user.id;
        token.accessToken = "1234567890";
      }
      return token;
    },
    session: ({ session, token }) => {
      session.user = token;
      session.accessToken = token.accessToken;
      return session;
    },
  },
});

Related

@ntubrian
Copy link

it now seem not work with @apollo/experimental-nextjs-app-support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment