-
-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature request: support authenticated queries with SSR #166
Comments
This specific feature is a tough one, as I mentioned in #168 (comment), using getInitialProps is completely possible to implement this feature, and if you want to propose a implementation around the existing code (after #169 is merged), I would be very grateful, and maybe add it in the docs as a copy-paste in your project solution, or add it in the gqless-react packages as scoped module "@gqless/react/nextjs" or something like that, but I don't think it should be added in the main module, since it would be a framework-specific solution |
What I mean by "authenticated queries" is graphql queries that have an authentication cookie or http header.
For a regular client-side SPA, it's easy to authenticate queries by modifying your
queryFetcher
. You can get the auth token from the browser environment & include it in thefetch
call:const queryFetcher: QueryFetcher = async function (query, variables) { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${window.localStorage["auth-token"]}`, }, body: JSON.stringify({ query, variables }), mode: "cors", }); const json = await response.json(); return json; };
(or use fetch option
credentials: 'include'
to have http cookies included automatically)For a server-side rendering, the
queryFetcher
needs to know about the page request (req
), so that it can forward the auth token that the browser sent in the page request:The objective becomes getting the
req
object in scope ofqueryFetcher
. It's currently possible, by creating one client per page request (which makes sense anyway), but currently that's not ergonomic and comes with limitations.I have pushed a demo project for reference: repo / deployment
In this demo, the components, instead of using a global singleton client, use the client we "provide" via React context. This way the component definitions are not tied to a single client. This is a common approach, used by apollo & urql & more.
The problem is that since there is no native
GqlessContext
in the@gqless/react
, which the hooks & HOC would use to read client from context, we need to wrap the whole react client to make the hooks read client from context.To avoid changing my components I created an adapted
useQuery
hook to (1) use theuseContext
hook to get the gqless clients (main client & react client) from context, & (2) call the hook and returns the result.The alternative would be to have a single hook that returns the entire gqless react client, which could be used like
const { posts } = useGqless().useQuery()
. This is not really pretty, or a simple/straightforward change to the codebase, just to add that http header.Also, using the
graphql
HOC becomes awkward since it's only accessible from within another component.Recommendation
The
ReactClient
should include aGqlessContext: React.Context<GqlessClient<GeneratedSchema>>
member which is consumed by the hooks & hoc. This would allow us to provide the client using<GqlessContext.Provider value={client}>
, or not do that (theclient
param passed tocreateReactClient
should be used as the default value), and use the same hooks & HOC either way.The text was updated successfully, but these errors were encountered: