apollographql / federation

šŸŒ Ā Build and scale a single data graph across multiple services with Apollo's federation gateway.
https://apollographql.com/docs/federation/
Other
666 stars 251 forks source link

RemoteGraphQLDataSource fails with self signed certificate in certificate chain #1761

Open msambol opened 2 years ago

msambol commented 2 years ago

I'm creating an instance of ApolloServer with ApolloGateway. I'm running it locally in dev but I get the following:

failed, reason: self signed certificate in certificate chain

Below is my code. I've tried to set strictSSL to false for make-fetch-happen. I've also tried setting NODE_TLS_REJECT_UNAUTHORIZED=0.

    class AuthenticatedDataSource extends RemoteGraphQLDataSource {
      willSendRequest({ request, context }) {
        request.http.headers.set('Authorization', context.token)
        request.http.timeout = 23500
      }
    }

    const gateway = new ApolloGateway({
      buildService({ url }) {
        return new AuthenticatedDataSource({ url })
      },
      fetcher: require('make-fetch-happen').defaults({
        strictSSL: false
      }),
      supergraphSdl: new IntrospectAndCompose({
        subgraphs: controllers
      }),
    })

    const server = new ApolloServer({
      gateway,
      plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
    })

Dependencies:

  "dependencies": {
    "@apollo/gateway": "^2.0.1",
    "@contrast/agent": "^2.16.4",
    "apollo-server": "^3.6.7",
    "apollo-server-core": "^3.6.7",
    "apollo-server-express": "^3.6.7",
    "bunyan": "^1.8.12",
    "bunyan-format": "^0.2.1",
    "dynamoose": "^1.3.0",
    "express": "^4.17.3",
    "express-bunyan-logger": "^1.3.3",
    "express-request-id": "^2.0.1",
    "graphql": "^16.3.0",
    "graphql-voyager": "^1.0.0-rc.31",
    "make-fetch-happen": "^10.1.2",
    "wait-port": "^0.2.9"
  },

Related: https://community.apollographql.com/t/apollo-gateway-local-dev-with-self-signed-certificates/2660.

Bug or am I doing something wrong?

msambol commented 2 years ago

@chrisrhymes Tagging you since you posted something similar here.

msambol commented 2 years ago

@chrisrhymes Tagging you since you posted something similar here.

@chrisrhymes Did you have success in getting past this?

rsarangu commented 2 years ago

running into same problem, were you able to fix this?

clenfest commented 2 years ago

After digging into the code, it looks like the issue is that the RemoteGraphQLDataSource objects use their own fetcher rather than the fetcher created in the gateway. ~It's definitely a bug, and as of now I don't see a workaround. I'll see if I can get a PR up for this tomorrow.~

clenfest commented 2 years ago

@msambol @rsarangu

After getting a bit of an assist from a colleague, it turns out I misread the code. RemoteGraphQLDataSource will in fact honor a custom fetcher passed in. I think if you change your buildService function to something like this it should work.

      buildService({ url }) {
        return new AuthenticatedDataSource({ 
          url,
          fetcher: fetcher.defaults({
            strictSSL: false
          }),
        })
      },

Let me know how that works.

msambol commented 2 years ago

@clenfest I was able to get this to work, thanks for digging! Not fetcher.defaults (I might be missing an import?), but the code below:

    const gateway = new ApolloGateway({
      buildService({ url }) {
        return new AuthenticatedDataSource({ 
          url,
          fetcher: require('make-fetch-happen').defaults({
            strictSSL: false
          })
        })
      },
      supergraphSdl: new IntrospectAndCompose({
        subgraphs: controllers
      })
    })

Note for others: in my original code I had fetcher as a param to ApolloGateway and not AuthenticatedDataSource (extends RemoteGraphQLDataSource). @clenfest Are there improvements that can be made to the docs here? I see it in both places, but maybe that's allowed.

Also note, you shouldn't use strictSSL: false in production!