Closed chris-snow closed 3 weeks ago
Phew, this is a difficult one - unfortunately React seems to be more opinionated than practical here :/
This is made even more difficult by the fact that useSuspenseQuery
will also run during SSR, so your server action will be executed from the server, but from outside your RSC.
For the SSR part, you could use something like https://github.com/phryneas/ssr-only-secrets, but that doesn't solve the problem at hand.
Passing your token down as a prop unencryped would expose it to the browser, which is generally a thing I'd try to avoid.
That said, maybe that's the core of your problem - calling your getAuthToken
function from the browser makes your auth token available to userland JavaScript again, which is what you want to avoid with the httpOnly
cookie in the first place, and it kinda ruins that layer of security.
Is there any way to establish that cookie directly between your browser and GraphQL server in the first place so you don't need that authentication header? That would be more secure and remove the need for the server action call.
Thanks for your response. The path I've decided to take, based on your suggestion, is altering my API so that it can accept either cookie or header based authentication.
The RSC client sends the header based auth, and the 'client' client sends credential based cookies. NextJS not making things easy but at least I have a workaround for the timebeing.
I still seem to be getting an unauthorized response on my very first RSC request, but I'll just have to live with that - I'm no longer getting the error I mentioned above.
Appreciate your help!
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.
I've swapped out useQuery for useSuspenseQuery and I'm now getting the following error:
ApolloError: Server Functions cannot be called during initial render. This would create a fetch waterfall. Try to use a Server Component to pass data to Client Components instead.
This is happening (assumption noted) because I am calling a server function to retrieve my authorization token when creating my authLink for the client side apollo client:
This error does not get shown when using useQuery, only when using useSuspenseQuery. I've attempted other methods of retrieving my token but unfortunately cannot reliably do this.
I could pass the token in as a prop from the ApolloWrapper, but unfortunately I have no way to reliably ensure that the token is regularly updated (i.e. read once on mount, it will become stale after a period of time).
I use PreloadQuery (as covered in the docs):
Parent component:
Child component: