Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introspection is broken in the beta #5641

Closed
ber4444 opened this issue Feb 22, 2024 · 11 comments
Closed

Introspection is broken in the beta #5641

ber4444 opened this issue Feb 22, 2024 · 11 comments

Comments

@ber4444
Copy link

ber4444 commented Feb 22, 2024

Version

4.0.0-beta.4

Summary

./gradlew :data:api:downloadApolloSchema --endpoint='https://our_domain.com/path' --schema=data/api/src/main/graphql/schema.graphqls --header="Subscription-Key: our_key" works with Apollo 3.8.2 but broken with the latest beta

Steps to reproduce the behavior

Run introspection after upgrading to the beta

Logs

> java.lang.Exception: Cannot execute pre-introspection query from https://our_domain.com/path: (code: 400)
  Missing Authorization Header on request
@martinbonnin
Copy link
Contributor

Thanks for the report. We'll look into it.

Double checking: the message says Missing "Authorization" Header but you're sending a "Subscription-Key" header. Is that expected?

Also, would be interesting to try using the introspection {} block in your Gradle build script:

apollo {
    service("service") {
        packageName.set("com.example")

        introspection {
            schemaFile.set(file("data/api/src/main/graphql/schema.graphqls"))
            endpointUrl.set("https://our_domain.com/path")
            headers.put("Subscription-Key", "our_key")
        }
    }
}

@martinbonnin
Copy link
Contributor

I made a TCP capture of both versions:

3.8.2

POST / HTTP/1.1
Subscription-Key: our_key
apollographql-client-name: apollo-gradle-plugin
apollographql-client-version: 3.8.2
Content-Type: application/json
Content-Length: 1539
Host: localhost:8080
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/4.9.3

4.0.0-beta.4

POST / HTTP/1.1
X-APOLLO-OPERATION-ID: c65bd3bd4f80b9bd27a37b753894d36d55b98c7d8458a1c56e60e4ac64ce23c0
X-APOLLO-OPERATION-NAME: PreIntrospectionQuery
Accept: multipart/mixed; deferSpec=20220824, application/json
Subscription-Key: our_key
apollographql-client-name: apollo-gradle-plugin
apollographql-client-version: 4.0.0-beta.4
Content-Type: application/json
Content-Length: 491
Host: localhost:8080
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/4.11.0

There are additional headers but nothing that should cause too many issues I think?

@ber4444
Copy link
Author

ber4444 commented Feb 22, 2024

Double checking: the message says Missing "Authorization" Header but you're sending a "Subscription-Key" header. Is that expected?

Yes, subscription key is the only header we need to set with lower version to make it work.

Also, would be interesting to try using the introspection {} block in your Gradle build script

We were already using this:

apollo {
        service("service") {
            packageName.set("com.xxx.data")
            schemaFile.set(file("src/main/graphql/schema.graphqls"))
            codegenModels.set("responseBased")
            introspection {
                endpointUrl.set("https://our_domain.com/path")
                headers.put("Subscription-Key", "our_key")
                schemaFile.set(file("src/main/graphql/schema.graphqls"))
            }
        }
    }

When I try to download via your Android Studio plugin, the error is No download schema tasks were found. Please configure an introspection or registry in the Apollo Gradle configuration.

@martinbonnin
Copy link
Contributor

martinbonnin commented Feb 22, 2024

Can you try from the command line?

./gradlew downloadServiceApolloSchemaFromIntrospection

Alternatively, it could be interesting to try different headers values with curl:

curl -v 'https://your_url' -X POST 
-H 'X-APOLLO-OPERATION-ID: c65bd3bd4f80b9bd27a37b753894d36d55b98c7d8458a1c56e60e4ac64ce23c0' 
-H 'X-APOLLO-OPERATION-NAME: PreIntrospectionQuery' 
-H 'Accept: multipart/mixed; deferSpec=20220824, application/json'  
-H 'Accept-Encoding: gzip, deflate, br' 
-H 'content-type: application/json' 
-H 'Connection: keep-alive' 
-H 'Subscription-Key: our_key' 
--data-raw '{"query":"query { __typename }","variables":{}}'

Try with and without the X-APOLLO-XYZ headers and Accept: multipart/mixed; deferSpec=20220824, application/json? Does that change anything?

@ber4444
Copy link
Author

ber4444 commented Feb 22, 2024

Execution failed for task ':data:api:downloadServiceApolloSchemaFromIntrospection'.
> java.lang.Exception: Cannot execute pre-introspection query from https://domain.com/path: (code: 400)
  Missing Authorization Header on request

Also tried with curl but it gave the same error, with or without those headers.

I did notice that introspection had issues recently (https://github.com/apollographql/apollo-kotlin/releases) and a fix was attempted in the latest release but looks like it's not the proper fix.

@martinbonnin
Copy link
Contributor

Also tried with curl but it gave the same error, with or without those headers.

That is surprising. This is the main difference with v3. The other big one being that the contents of the introspection query changed.

v4 implements 2-step introspection in order to get the list of supported features dynamically. As GraphQL is evolving, introspection supports more features like __InputValue.isDeprecated for an example and we need 2-step introspection to determine that.

Could it be that your backend requires some whitelisting of the queries or rejects the PreIntrospectionQuery?

query PreIntrospectionQuery {
  __schema {
    types {
      ...TypeFields
    }
  }
}

fragment TypeFields on __Type {
  name
  fields {
    name
    args {
      name
    }
  }
}

@martinbonnin
Copy link
Contributor

PS: if you're willing to privately share the url and a Subscription-Key, I'm pretty sure we can get to the bottom of is quite quickly. Feel free to dm me at martin at apollographql.com

@martinbonnin
Copy link
Contributor

@ber4444 thank you for providing details in DM but unfortunately I haven't been able to reproduce the issue neither in 3.8.2 nor 4.x. It looks like your endpoint is secured through different means and without more details, It's pretty hard to debug.

4.x uses different queries to implement 2-step introspection which means the HTTP requests are different and my guess is that some security policies have been set against the 3.x behaviour and should be updated for 4.x.

I'm going to close this one. Let me know if anything new comes up.

Copy link
Contributor

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Kotlin usage and allow us to serve you better.

@ber4444
Copy link
Author

ber4444 commented Mar 12, 2024

Beta 5 resolved this

@martinbonnin
Copy link
Contributor

Glad to hear that! Thanks for the update!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants