apollo-client-nextjs: useSuspenseQuery not sending cookies on Server Side query
Hi there,
I may be missing something simple here but I have an apollo-provider that is pretty standard, however we use supabase auth and the session is set in cookies.
Obviously the cookie is present when the user refreshes the query page, but its not until the client re-initiates the query (which I don’t think would happen if this issue was solved) that the server sees the cookies passed. The httpLink and client set up is as follows:
` const isServer = typeof window === “undefined”; const httpLink = new HttpLink({ uri: GRAPHQL_URI, credentials: “include” });
return new NextSSRApolloClient({ cache: apolloCache, link: isServer ? ApolloLink.from([new SSRMultipartLink({ stripDefer: true }), httpLink]) : httpLink, }); }; `
I know the cookie is available because I can set it as an authorization header which does get fired in the query on the server side but I’d rather not have to “hack” it that way, Is there a way to ensure that even when query is processed on the server side that it includes the cookies?
Thanks in advance.
About this issue
- Original URL
- State: open
- Created a year ago
- Reactions: 4
- Comments: 15 (6 by maintainers)
We have encountered the same issue and it is so frustrating. Basically it blocks SSR support for hooks (unless we use a really smart but still hacky solution above). I have created a discussion in the Next.js repo, hopefully it will gain some attention.
Here’s what I did, make a new env variable name it anything you’d like but don’t start it with “NEXT_PUBLIC_” (otherwise that will be bundled in browser) for instance I chose :
ENCRYPTION_KEY="12345678"
Now before passing your cookies to a child client component encrypt it using that key in your layout file, in your client component (ApolloWrapper) decrypt it only if
typeof window === "undefined"
and attach it.Since no one will have access to your encryption key all your cookies will be encrypted and decrypted safely on the server side, but remember to add some random data into your object before encryption otherwise it might still be easy to crack.
It’s not the best we could do but it’s probably the best we can do, if NextJS team added some global request object for the server side, we didn’t have to deal with all these non-sense.
That’s incredibly hacky, but also a great solution - well done!
@rval I’d love to give you a better answer, but this seems like an architectural oversight on the side of Next.js - we won’t be able to give you any better advice until they come up with a better way of doing this.
Maybe open an issue over there, and if they come up with something better, please report back here? I’d love to hear about that 😃
Forgive me if I’m missing something obvious, but if you have an HTTP-only cookie that holds a sensitive credential, and then pass it to a client component, don’t you risk exposing it to client-side code and introducing an XSS vulnerability?
Is the thinking here that unless you’re actually rendering the cookie value it shouldn’t show up in any part of the browser payload? Edit: looks like props passed to client components can show up in the browser payload, even if they’re not used directly: