using apollo, cookie in response header but not being set

Viewed 6464

I'm developing a user login/register feature as part of a larger project and am working on localhost (apollo server and react apollo front-end). I'm using express-session for my sessions.

When submitting my login I can see the response header has set-cookie inside, but its not set in Application->Cookies.

I've tried different browsers, using createHttpLink, apollo-boost, and using include & same-origin (using same-origin).

I've been trying to get this working for 2 weeks now and have run out of things to try, this was my last option! I know its going to be something really trivial but I just can't see it.

If I use GraphqL Playground and change the settings to include credentials, I can see the cookie being set there.

Server is running on localhost:8080/graphql Client is running on localhost:3000

Client:

const client = new ApolloClient({
    link: new HttpLink({
        uri: 'http://localhost:8080/graphql',
        credentials: 'same-origin',
    }),
    cache: new InMemoryCache()
});

Cors:

app.use(
    cors({ 
        origin: 'http://localhost:3000',
        credentials: true
    })
);

Express-Session:

app.use(
    session({
        name: "sess",
        secret: process.env.SESSION_SECRET,
        resave: false,
        saveUninitialized: false,
        cookie: {
            httpOnly: true,
            secure: false,
            maxAge: 1000 * 60 * 60 * 24 * 7,
        },
    })
);

Response Cookie:

HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Type: application/json
Content-Length: 69
set-cookie: sess=s%3AAZXnGb5BVc1aAOwH6zBNiT8mB6Ebf75k.in%2BPU1OvxymDPdPIZBf8%2FQzrRmM0S04tXFzXDwYCnk8; Path=/; Expires=Sat, 03 Nov 2018 13:59:57 GMT; HttpOnly
Date: Sat, 27 Oct 2018 13:59:57 GMT
Connection: keep-alive
5 Answers

I had the same issue. Incase you're still looking for an answer after 2 years set credentials in the client to "include" like this:

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
  credentials: 'include'
});

I tried to fix it by using express. But it didn't work with Apollo GraphQL.

const corsOptions = {
    origin: "http://localhost:3000",
    credentials: true
  };
app.use(cors(corsOptions));

So, I tried configuring cors inside GraphQL server and It Worked.

For Apollo Server

const corsOptions = {
    origin: "http://localhost:3000",
    credentials: true
  };

const server = new ApolloServer({
  typeDefs,
  resolvers,
  cors: corsOptions
});

server.listen().then(({ url }) => {
  console.log(` Server ready at ${url}`);
});

For GraphQL Yoga

const options = {
  cors: corsOptions
};

server.start(options, () =>
  console.log("Server is running on http://localhost:4000")
);

The issue seems to be one of CORS configuration. First, change the HttpLink to use credentials: 'include'; then try this CORS middleware:

app.use(
  cors({ 
    origin: 'http://localhost:3000',
    credentials: true,
    allowedHeaders: ['Content-Type', 'Authorization'],
  })
);

If you still get the error The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. then it suggests that the CORS middleware is not correctly setting Access-Control-Allow-Origin: http://localhost:3000 (your example shows it is returning * but I'm not sure if this was a copy/paste issue, since the cors module docs suggest this should work.)

I managed to solve this by passing the CORS settings to the applyMiddleware directly.

if you are using cors package from npm, then its creating the issue, so use default graphql server cros option like bellow:

server

    await server.start()
    server.applyMiddleware({
        app, cors: {
            origin: true,
            credentials: true
        }
    })

client:

const client = new ApolloClient({
  uri: 'http://localhost:2424/graphql',
  cache: new InMemoryCache(),
  credentials: 'include'
})

Related