8

I have tried following the instructions on Apollo Client for sending cookies along with the graphql request, but the express server is not receiving any cookies and when I inspect the request it shows that no cookies are being sent with the response.

Following this page:

https://www.apollographql.com/docs/react/recipes/authentication.html

My code is

const link = createHttpLink({
  uri: 'http://localhost:3000/api/graphql',
  opts: {
    credentials: 'include',
  }
});

const client = new ApolloClient({
  link,
  cache: new InMemoryCache()
});

My setup is very simple, I am just using the create-react-app server on localhost:3000, sending requests on for the api to localhost:5000 (express api server). I can set and retrieve cookies via localhost:3000 on other routes, only Apollo Client is not sending them.

wbruntra
  • 1,021
  • 1
  • 10
  • 18

4 Answers4

4

I do not understand this why the documentation says what it does, although perhaps a developer with more experience would not have had a problem.

Anyway, the less experienced developer should note that instead of:

const link = createHttpLink({
  uri: 'http://localhost:3000/api/graphql',
  opts: {
    credentials: 'include',
  }
});

It should just be:

const httpLink = createHttpLink({
  uri: 'http://localhost:3000/api/graphql',
  credentials: 'same-origin'
});

In other words, there is no separate opts object within the createHttpLink configuration object.

wbruntra
  • 1,021
  • 1
  • 10
  • 18
1

There is a helper from the Apollo Client library called createNetworkInterface and you can import it like so:

import ApolloClient, { createNetworkInterface } from 'apollo-client';

Then you can implement it like so:

const networkInterface = createNetworkInterface({
  uri: 
});

The Apollo Client assumes that your graphql client on the express side is listening on the endpoint /graphql. You can verify this by going to your server.js file.

You should see something like:

// Instruct Express to pass on any request made to the '/graphql' route
// to the GraphQL instance.
app.use(
  '/graphql',
  expressGraphQL({
    schema,
    graphiql: true
  })
);

So the uri: option you specify is still GraphQL like so:

const networkInterface = createNetworkInterface({
  uri: '/graphql'
});

We do this because whenever we create our own networkInterface it no longer assumes the uri is /graphql so we have to directly say it.

The part that really matters is the opts: property like so:

const networkInterface = createNetworkInterface({
  uri: '/graphql',
  opts: {
    credentials: 'same-origin'
  }
});

This is saying its safe to send along cookies whenever it makes a query to the backend server. So you take this networkInterface and pass it along to the Apollo Client like so:

const networkInterface = createNetworkInterface({
  uri: '/graphql',
  opts: {
    credentials: 'same-origin'
  }
});

const client = new ApolloClient({
  networkInterface,
  dataIdFromObject: o => o.id
});

So that is pretty much it for getting Apollo to send along cookies along with every single request it makes to the backend.

Daniel
  • 14,004
  • 16
  • 96
  • 156
1

You code should be

const link = createHttpLink({
  uri: 'http://localhost:3000/api/graphql',
  credentials: 'include'
});

const client = new ApolloClient({
  link,
  cache: new InMemoryCache()
});

See official doc for details: apollo client cookie

Also make sure that your server returns correct value for the 'Access-Control-Allow-Origin' header. It should not be equal '*'

timthedev07
  • 454
  • 1
  • 6
  • 17
Roman Podlinov
  • 23,806
  • 7
  • 41
  • 60
0

credentials are supposed to be mentioned under createHttpLink

const link = createHttpLink({
  uri: 'http://localhost:3000/api/graphql',
  credentials: 'include'
});

const client = new ApolloClient({
  link,
  cache: new InMemoryCache()
});

In case, you are using ApolloClient.split, then you can use

const httpLink = ApolloLink.split(
  (operation) => operation.getContext().hasUpload,
  createUploadLink({uri:URI, credentials: 'include'}),
  new HttpLink({uri:URI}),
);

 new ApolloClient({
  link:httpLink,
  cache:new InMemoryCache()
 });