0

How to pass Cookie headers from gatsby-source-graphql?

I'm using the gatsby-source-graphql (https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-source-graphql) and recently had to implement AWS Cloudfront Signed Cookies to authorise users to acccess a private staging environment, for this reason the requests to the graphql endpoint, handled by the plugin, need to have the cookie in the request header, which I do by:

{
  resolve: 'gatsby-source-graphql',
  options: {
    cookie: 'var1=val1; var2=val2; '
  }
}

The above fails,

ServerParseError: Unexpected token < in JSON at position 0

If disabling Signed Cookies and making the endpoint public, it works.

And, if I keep it private again and test with curl, works:

curl --cookie 'var1=val1; var2=val2; ' graphql_endpoint.com

I tried to figure out why the Cookie header is not passed, but seems that the problem is in a different plugin that the plugin above uses called 'apollo-link-http' (https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/gatsby-node.js)

Meanwhile, looking at the apollo-http-link (https://www.apollographql.com/docs/link/links/http/) and a issue reported here (https://github.com/apollographql/apollo-client/issues/4455), I tried:

{
  resolve: 'gatsby-source-graphql',
  options: {
    typeName: 'FOOBAR',
    fieldName: 'foobar',
    createLink: (pluginOptions) => {
        return createHttpLink({
          uri: process.env.GATSBY_GRAPHQL_API_URL,
          credentials: 'include',
          headers: {
            cookie: "CloudFront-Policy=xxxxx_; CloudFront-Key-Pair-Id=xxxxx; CloudFront-Signature=xxxxxxxxxx; path=/;",
          },
          fetch,
        })
    },
  }
},

Without success, the same error as before.

Also tried to use the fetch options for node-fetch,

{
  resolve: 'gatsby-source-graphql',
  options: {
    typeName: 'FOOBAR',
    fieldName: 'foobar',
    url: process.env.GATSBY_GRAPHQL_API_URL,
    fetchOptions: {
        credentials: 'include',
        headers: {
            cookie: "CloudFront-Policy=xxxxx_; CloudFront-Key-Pair-Id=xxxxx; CloudFront-Signature=xxxxxxxxxx; path=/;",
        },
    },
  }
},

As you can see fetchOptions here (https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/gatsby-node.js)

No success! This is probably a bug.

punkbit
  • 7,347
  • 10
  • 55
  • 89

1 Answers1

1

After spending a lot of time looking at the docs and other reports, I found a solution based on the attempts I've originally posted.

I started by looking at the browser version, and check the cookie header property name to avoid any typos. Which I've determined it should be "Cookie", as most examples I found mention '.cookie', etc.

enter image description here

With that said, I've checked the documentation for all the related packages and source code:

https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-source-graphql
https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/gatsby-node.js

https://www.apollographql.com/docs/link/links/http/
https://github.com/apollographql/apollo-client/issues/4455

Finally, I declared the headers cookie parameter and in a separate property, the options for the node-fetch package:

https://github.com/bitinn/node-fetch

The result:

{
  resolve: 'gatsby-source-graphql',
  options: {
    typeName: 'FOOBAR',
    fieldName: 'foobar',
    url: process.env.GATSBY_GRAPHQL_API_URL,
    headers: {
        Cookie: 'CloudFront-Policy=xxxxx_; CloudFront-Key-Pair-Id=xxxxx; CloudFront-Signature=xxxxxxxxxx; path=/;'
    },
    credentials: 'include',
  }
},

What happens above, is that the "credentials include" allow cross-browser origin requests and enables cookies (https://www.apollographql.com/docs/react/networking/authentication/#cookie)

Hope that this helps someone else in the future, as it's not trivial.

punkbit
  • 7,347
  • 10
  • 55
  • 89