How to Use JWT with GraphQL for Secure Authentication
To use
JWT with GraphQL, include the token in the request headers and verify it in the GraphQL server's context function. This allows you to authenticate users and control access to resolvers based on the token's validity and claims.Syntax
Using JWT with GraphQL involves these key parts:
- Token in Headers: The client sends the JWT in the
Authorizationheader. - Context Function: The GraphQL server extracts and verifies the token in the context setup.
- Resolvers: Access user info from context to allow or deny actions.
javascript
const { ApolloServer, gql } = require('apollo-server'); const jwt = require('jsonwebtoken'); const typeDefs = gql`type Query { hello: String }`; const resolvers = { Query: { hello: (parent, args, context) => { if (!context.user) throw new Error('Not authenticated'); return `Hello, ${context.user.name}`; }, }, }; const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { const token = req.headers.authorization || ''; try { const user = jwt.verify(token.replace('Bearer ', ''), 'your_secret_key'); return { user }; } catch { return {}; } }, }); server.listen();
Example
This example shows a simple Apollo Server that checks a JWT from the Authorization header and uses it to greet the authenticated user.
javascript
const { ApolloServer, gql } = require('apollo-server'); const jwt = require('jsonwebtoken'); const typeDefs = gql` type Query { hello: String } `; const resolvers = { Query: { hello: (parent, args, context) => { if (!context.user) { throw new Error('Not authenticated'); } return `Hello, ${context.user.name}`; }, }, }; const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { const authHeader = req.headers.authorization || ''; const token = authHeader.replace('Bearer ', ''); if (!token) return {}; try { const user = jwt.verify(token, 'your_secret_key'); return { user }; } catch (e) { return {}; } }, }); server.listen().then(({ url }) => { console.log(`Server ready at ${url}`); });
Output
Server ready at http://localhost:4000/
Common Pitfalls
Common mistakes when using JWT with GraphQL include:
- Not sending the token in the
Authorizationheader or using the wrong format. - Failing to verify the token in the context, which leaves your API unprotected.
- Not handling token expiration or errors properly, causing unexpected failures.
- Exposing sensitive data in the token or context without checks.
javascript
/* Wrong: Not verifying token in context */ const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { // No token verification here return {}; }, }); /* Right: Verify token and handle errors */ const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { const token = req.headers.authorization?.replace('Bearer ', '') || ''; try { const user = jwt.verify(token, 'your_secret_key'); return { user }; } catch { return {}; } }, });
Quick Reference
- Send JWT in
Authorization: Bearer <token>header. - Verify JWT in GraphQL
contextfunction. - Use verified user info in resolvers for access control.
- Handle token errors gracefully to avoid crashes.
Key Takeaways
Always verify JWT tokens in the GraphQL context to authenticate users.
Send the JWT in the Authorization header with the Bearer scheme.
Use user info from the verified token inside resolvers to control access.
Handle token verification errors to prevent server crashes.
Never expose sensitive data without proper checks in your GraphQL API.