-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Client preset uses a different hash than apollo server #9108
Comments
You should check that the server and the client use the same version of graphql. |
They do, I'm forcing a resolution to If you view my links above, its pretty clear that client preset is generating the hash using
|
Again, ideally, this hashing would be possible in a plugin so y'all don't need to maintain compatability with every single possible GraphQL server. While Apollo Server has a pretty strict requirement with sha256, I have no clue what other servers require. For this hashing to be done in a plugin, either the 'executable document' node needs to be passed as a plugin argument or some sort of stable version of |
Does apollo server complain about the hashes (e.g. raise an error)? In the end it is just a hashtable lookup so the actual hashing algorithm should be irrelevant for the server. |
Yes, apollo server complains about the hashes. It does server side verification to make sure folks are not passing mismatched hashes and queries here: https://github.com/apollographql/apollo-server/blob/8cbc61406229653454e50ea98f11dbe834e036b5/packages/server/src/requestPipeline.ts#L158-L164 I think this is a good idea since it prevents potential foot guns of folks incorrectly caching queries that are missing fields etc. It would not surprise me if other server implementations were to also do this. |
Also, FWIW I've been trying to use
Part of this seems to be due the fact that each plugin executes independently rather than as a pipeline (like webpack for example). This makes it really easy for there to be disagreement between plugins about what the 'final' executable document should look like. This disagreement makes hashing very error prone and could cause all sorts of problems down the road. I realize that it would not be a trivial change, but conceptually a pipeline architecture would both be more performant and easier to extend via plugins rather than having each plugin recompute/regenerate everything themselves. |
As the option If you want to alter the document's I don't get why Apollo Server needs to verify the hash and the document string, there is no security issue as the server owner needs to provide the persisted operation hash map? Reading what you are writing I think you are talking about Automatic Persisted Queries (APQ), which are not the same as persisted documents and are not related to this codegen option. Aside from that, I am happy to accept a PR that allows passing a custom hashing function, e.g. like the following: import { type CodegenConfig } from '@graphql-codegen/cli'
const hashFn = (document: DocumentNode): string => {
// whatever u wanna do here
}
const config: CodegenConfig = {
schema: 'schema.graphql',
documents: ['src/**/*.tsx'],
generates: {
'./src/gql/': {
preset: 'client',
presetConfig: {
persistedDocuments: {
hashFn,
}
}
}
}
}
Soon the client preset will no longer use the typescript and typescript-operations underneath. As we are planning to re-architecture the code generation. |
I'm a bit confused then considering your docs refers to them as the same thing: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#persisted-documents
The above docs even link to these docs: https://the-guild.dev/graphql/yoga-server/docs/features/persisted-operations
Which links to docs on APQ. |
Its not a security issue, its a correctness issue and prevents a common footgun. Lets say my hashing is done on this query: query GetMyThing {
getThing {
id
name
__typename
}
} but the query I send to server is actually: query GetMyThing {
getThing {
id
name
}
} Now the server has an incorrect value in its cache and needs to be cleared before the query hashes work correctly. This is even more problematic if the server is a 3rd party server. |
You will never send an operation document to the server when using persisted documents. You will always ONLY send the hash. In Yoga we clearly dofferenciate between these two implementations: |
If you want to use APQ the persisted operations feature in the client preset is completly irrelevant for you. |
Which packages are impacted by your issue?
@graphql-codegen/client-preset
Describe the bug
Currently client preset uses sha1 while Apollo Server uses sha256 with no plans to make it configurable.
Ideally the exact hashing behavior here would be configurable without me needing to use
unstable_onExecutableDocumentNode
or rewrite my own version ofClientSideBaseVisitor
.Ideally, I would like to write my own plugin similar to
graphql-codegen-persisted-query-ids
that could operate on the document nodes generated by upstream plugins. Currently, thedocuments
passed into a plugin are the 'raw' documents from source, but ideally the could be the documents generated by 'upstream' plugins.The benefit of allowing me access to the generated documents in a plugin is it would allow me to use whatever framework specific hashing I need to do without y'all needing to support every single possible target out there.
Your Example Website or App
N/A linked directly to relevant code above
Steps to Reproduce the Bug or Issue
N/A linked directly to relevant code above
Expected behavior
At a minimum the hash would match what Apollo Server is using since you refer to the "APQ Specification of Apollo" in your current docs: https://the-guild.dev/graphql/yoga-server/docs/features/automatic-persisted-queries.
Best case, I would be able to write a plugin that hashes the document nodes myself without using unstable APIs or effectively duplicating core code.
Screenshots or Videos
No response
Platform
graphql
version: 16.6.0@graphql-codegen/*
version(s): 3.2.1Codegen Config File
No response
Additional context
No response
The text was updated successfully, but these errors were encountered: