I'm trying to get Neo4J + graphQL lib 4.0.0 + authentication/authorization via JWT. I managed to do it with graphQL 3.0.0 but can't now update to 4.0.0.
My base code relates on the documentation OGM/Examples/Custom Resolvers
I get the following error:
"message": "Type mismatch for parameter 'jwt': expected Map, Node, Relationship, Point, Duration, Date, Time, LocalTime, LocalDateTime or DateTime but was String (line 3, column 87 (offset: 113))\n\"WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND this.id = coalesce($jwt.sub, $jwtDefault)), \"@neo4j/graphql/FORBIDDEN\", [0])\"\
This seems to be related to APOC translation.
I have the following in my schema:
type JWT @jwt {
roles: [String!]!
}
My base type for User is:
type User {
id: ID @id
username: String!
password: String! @private
roles: [String!]
}
I tried different simple things in the schema:
type User @authorization(validate: [{ when: [BEFORE], where: {node: {id: "$jwt.sub" } } }]){
# or
type User @authorization(validate: [
{ where: { node: { id: "$jwt.sub" } } }
{ where: { jwt: { roles_INCLUDES: "admin" } } }
]) {
# or
type User @authentication(operations: [DELETE], jwt: { roles_INCLUDES: "admin" }){
When querying
query Users {
users {
username
roles
}
}
with header
{
"Authorization" : "Bearer <jwt>"
}
I get the following error:
"message": "Type mismatch for parameter 'jwt': expected Map, Node, Relationship, Point, Duration, Date, Time, LocalTime, LocalDateTime or DateTime but was String (line 3, column 87 (offset: 113))\n\"WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND this.id = coalesce($jwt.sub, $jwtDefault)), \"@neo4j/graphql/FORBIDDEN\", [0])\"\
This seems to be related to APOC translation.
My server is as follows:
const neoSchema = new Neo4jGraphQL({
typeDefs,
driver,
resolvers,
features: {
authorization: {
key: signingKey,
}
}
});
Promise.all([neoSchema.getSchema(), ogm.init()]).then(([schema]) => {
const server = new ApolloServer({
schema,
});
startStandaloneServer(server, {
context: async ({ req }) => {
//console.log(req.headers);
return { jwt: req.headers.authorization }},
}).then(({ url }) => {
console.log(` Server ready at ${url}`);
});
});
Any help would be greatly appreciated!
I looks like you're trying to decode the JWT with the GraphQL library since you have the below in the library config.
Also, if the token you're setting to the
jwt
field on the request context is encoded, that would explain why the error gets thrown about it being a string.The documentation here https://neo4j.com/docs/graphql-manual/current/authentication-and-authorization/configuration/ says
You should pass the encoded token into the request context on the
token
field.Try setting the request context with
return { token: req.headers.authorization }}
instead.