RevereCRE/relay-nextjs

Authenticated request client side

monoppa opened this issue · 2 comments

Hi! Awesome library you have here.

Wondering if by any chance you have a nice way of doing authenticated requests on client-side.

Any chance we could expose ctx from next for createClientEnvironment?
Would this be a good idea?

EDIT: Forked the package, the code below will not work.
May I have other ideas how to have make authenticated requests client-side via relay-nextjs using withRelay?

It would look like this for getClientEnvironment

// we receive `ctx` here to determine authenticated headers
export function createClientNetwork(ctx) {
  return Network.create(async (params, variables) => {
    const response = await fetch('/api/graphql', {
      method: 'POST',
      credentials: 'include',
      headers: {
        'Content-Type': 'application/json',
        // we set the auth header here
        headers['x-auth'] = ctx.token
      },
      body: JSON.stringify({
        query: params.text,
        variables,
      }),
    });

    const json = await response.text();
    return JSON.parse(json, withHydrateDatetime);
  });
}

let clientEnv: Environment | undefined;
// this is where we will have access for the `ctx`
export function getClientEnvironment(ctx) {
  if (typeof window === 'undefined') return null;

  if (clientEnv == null) {
    clientEnv = new Environment({
     // pass ctx to createClientNetwork
      network: createClientNetwork(ctx),
      store: new Store(new RecordSource(getRelaySerializedState()?.records)),
      isServer: false,
    });
  }

  return clientEnv;
}

This is a bit tricky for two reasons:

  1. I'm not sure having the Relay environment change network after initializing works?

  2. Requests must be made on both the client side and server side, so using local storage based authentication won't work because it's not available on the server.

For these reasons I recommend using cookies for your auth solution.

Got it! Actually had the same realization hence closed the issue.
Appreciate your reply. Thanks!