Closed DanielAtCosmicDNA closed 3 weeks ago
Many thanks for raising this bug report @DanielAtCosmicDNA. :bug: We will now attempt to reproduce the bug based on the steps you have provided.
Please ensure that you've provided the necessary information for a minimal reproduction, including but not limited to:
If you have a support agreement with Neo4j, please link this GitHub issue to a new or existing Zendesk ticket.
Thanks again! :pray:
Hi @DanielAtCosmicDNA!
At first look it seems that this is highly related to your usage of startServerAndCreateNextHandler
. Do you see the same behaviour without using this?
DEBUG=@neo4j/graphql:auth
I have just created a reproduction repo.
So answering your question, yes. The same behaviour is happening without nextjs and @as-integrations/next.
@DanielAtCosmicDNA I don't see any problems when using your reproduction code.
Can you specify a particular combination of type definitions and query/mutation you use which can showcase the issue?
@DanielAtCosmicDNA I don't see any problems when using your reproduction code.
Can you specify a particular combination of type definitions and query/mutation you use which can showcase the issue?
When I run a simple query:
query Query {
users {
id
}
}
With Authorization header: Bearer eyJh.....
and then you simply run:
npm run start
The output in the terminal is:
@neo4j/graphql:auth Verifying JWT using secret +0ms
@neo4j/graphql:auth TypeError: Key for the RS256 algorithm must be one of type KeyObject or CryptoKey. Received an instance of Buffer
at asymmetricTypeCheck
The next step would be to add @authentication to name field here.
And performing a simple query with and without the authorisation header:
query Query {
users {
id
name
}
}
It should behave differently as expected, only allowing the name to be displayed in case of successful authentication.
@DanielAtCosmicDNA I don't see any problems when using your reproduction code.
Can you spot a difference in our setups?
@DanielAtCosmicDNA I don't see any problems when using your reproduction code.
Can you spot a difference in our setups?
I cloned your repo and tried your code and it worked fine. How are you creating your JWT?
@DanielAtCosmicDNA if you make a dummy key and JWT using https://jwt.io/ do you still encounter the same error?
@DanielAtCosmicDNA I don't see any problems when using your reproduction code.
Can you spot a difference in our setups?
I cloned your repo and tried your code and it worked fine. How are you creating your JWT?
NextAuth created it for me. Now that you pointed that out, I have just tested with http://jwtbuilder.jamiekurtz.com/. And the JWT here is decoded correctly.
@DanielAtCosmicDNA if you make a dummy key and JWT using https://jwt.io/ do you still encounter the same error?
What is weird, though is that the original JWT I used and which has a problem is decoded correctly by https://jwt.io/. It seems to me there is something amiss here.
@DanielAtCosmicDNA https://medium.com/@fatih969692/understanding-the-incompatibility-between-jwt-verify-and-nextauth-js-c41adcd16fd0 this seems highly relevant
I created a new branch JWT decryption and when I run:
NEXTAUTH_JWT_TOKEN=eyJh... npm run convert
I get the following error:
neo4j-graphql-authentication/node_modules/jose/dist/node/esm/jwe/compact/decrypt.js:13
throw new JWEInvalid('Invalid Compact JWE');
@DanielAtCosmicDNA I wonder if you can use the built-in NextJS getToken
https://next-auth.js.org/configuration/options#jwt-helper ?
@DanielAtCosmicDNA I wonder if you can use the built-in NextJS
getToken
https://next-auth.js.org/configuration/options#jwt-helper ?
I can get the JWT token with the following route handler:
import { NextResponse } from 'next/server'
import { getToken } from 'next-auth/jwt'
const secret = process.env.NEXTAUTH_SECRET
const GET = async (request) => {
// Get the token from the request
const token = await getToken({ req: request, secret, raw: true })
return NextResponse.json({ token })
}
export { GET }
But it results in the following error:
@neo4j/graphql:auth Verifying JWT using secret +1s
@neo4j/graphql:auth JWSInvalid: Invalid Compact JWS
Now if I try to decode with convert script I have the following error:
node_modules/jose/dist/node/esm/runtime/decrypt.js:65
throw new JWEDecryptionFailed();
How about something like this, where you just pass the result in the context?
export default startServerAndCreateNextHandler(server, {
context: async ({ req }) => {
const token = await getToken({ req, secret });
return {
token
}
}
})
Not sure of the exact values.
How about something like this, where you just pass the result in the context?
export default startServerAndCreateNextHandler(server, { context: async ({ req }) => { const token = await getToken({ req, secret }); return { token } } })
Not sure of the exact values.
Following https://neo4j.com/docs/graphql/current/security/configuration/ I changed the code to:
export default startServerAndCreateNextHandler(server, {
context: async (req) => {
// const token = headers.authorization
const secret = process.env.NEXTAUTH_SECRET
const jwt = await getToken({ req, secret })
return {
jwt
}
}
})
And it is now working perfectly fine. Many thanks for your insights in this regard @mjfwebb !
Running the following code as an api route within NextJS pages/api/graphql/endpoint.js:
with a
schema.graphql
file in the same folder:And running the server with:
After adding the following line to
node_modules/jose/dist/node/cjs/lib/check_key_type.js
just to add this console.log:where @/app/libs/neo4j.js is:
results in:
after making any queries or mutations at the endpoint: http://localhost:3000/api/graphql/endpoint
Additionally, if @authentication marker is added to the field name, a query results in unauthenticated error.
Expected behavior It was expected that the JWT authentication would work without any problem with or without authentication mark in the name field.
System (please complete the following information):
Additional context "@apollo/server": "^4.10.4", "@neo4j/graphql": "^5.4.4", "@neo4j/graphql-ogm": "^5.4.5", "@as-integrations/next": "^3.0.0", "neo4j-driver": "^5.22.0",