Open Dakuan opened 2 months ago
this is my workaround, ugly but works:
import { HttpLink } from "@apollo/client";
import {
NextSSRInMemoryCache,
NextSSRApolloClient,
} from "@apollo/experimental-nextjs-app-support/ssr";
import { registerApolloClient } from "@apollo/experimental-nextjs-app-support/rsc";
import { runWithAmplifyServerContext } from "../amplify/amplifyServerUtils";
import { fetchAuthSession } from "aws-amplify/auth/server";
import { cookies } from "next/headers";
export const getClient = async () => {
const token = await runWithAmplifyServerContext({
nextServerContext: { cookies },
operation: async (contextSpec) => {
const session = await fetchAuthSession(contextSpec);
return session.tokens?.accessToken.toString();
},
});
const { getClient } = registerApolloClient(() => {
const httpLink = new HttpLink({
uri: "http://localhost:4000/graphql",
headers: {
Authorization: `Bearer ${token}`,
},
});
return new NextSSRApolloClient({
cache: new NextSSRInMemoryCache(),
link: httpLink,
});
});
return getClient();
};
That sounds like a reasonable request - I'll take a look at that in a bit, but right now we're in the middle of a big refactor we have to finish first (#189, #193) - but I'll get to it after that :)
@Dakuan is there any reason you couldn't use the setContext
link for this? This handles async functions and you can set headers that will be sent in the request from this link.
const tokenLink = setContext(async () => ({
headers: {
Authorization: `Bearer ${await getToken()}`
}
})
yeah, thats what i tried originally but it complained about client code running on the server
I'm curious how you set that up. This doesn't have anything to do with React and is part of the Apollo Client link chain. Did you perhaps try and use React context for this? That is something completely different 🙂
Here is a more full example to show what I mean:
import { setContext } from "@apollo/client/link/context";
async function getToken() {
return runWithAmplifyServerContext({
nextServerContext: { cookies },
operation: async (contextSpec) => {
const session = await fetchAuthSession(contextSpec);
return session.tokens?.accessToken.toString();
},
});
}
export const { getClient } = registerApolloClient(() => {
const contextLink = setContext(async () => ({
headers: {
Authorization: `Bearer ${await getToken()}`,
}
}));
const httpLink = new HttpLink({
uri: "http://localhost:4000/graphql",
});
return new NextSSRApolloClient({
cache: new NextSSRInMemoryCache(),
link: contextLink.concat(httpLink),
});
});
Be really handy if
registerApolloClient
was async...here's what im trying to doall my auth its handled by aws congnito / amplify. I can get my jwts using the amplify utils, and them pass them to the API. But, its an async process, so needs to live in an async fn...