Authentication in GraphQL — Complete Guide
In this tutorial, you will learn about Authentication in GraphQL. We cover key concepts, practical examples, and best practices to help you master this topic.
Authentication in GraphQL verifies who the client is. Unlike REST where auth can be endpoint-specific, GraphQL requires auth at the transport level, typically through the context object. The auth Strategy determines how credentials flow through the request lifecycle.
What You'll Learn
- JWT token-based authentication in context
- OAuth2 integration patterns
- API key authentication for service accounts
- Websocket authentication for subscriptions
- Auth middleware and context injection
Why It Matters
Authentication is the first line of defense for any API. GraphQL's single endpoint makes authentication a critical concern. Proper auth ensures only verified clients access your schema.
Real-World Use
GitHub uses OAuth2 tokens passed in the Authorization header. Shopify uses API keys for public apps and OAuth for private apps. Both verify tokens in a context function before resolvers execute.
flowchart LR
Client[Client] -->|Request + Auth Header| Server[GraphQL Server]
Server --> Context[Context Function]
Context --> Verify[Verify Token]
Verify -->|Valid| User[Attach User to Context]
Verify -->|Invalid| Error[Return Auth Error]
User --> Resolvers[Resolver Execution]
Teacher Mindset
Authentication happens once per request in the context function. Do not check authentication inside individual resolvers. The context function verifies credentials and attaches user information for downstream use.
Code Examples
// Example 1: JWT authentication in context
const server = new ApolloServer({
typeDefs,
resolvers,
context: async ({ req }) => {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) return { user: null };
try {
const user = await jwt.verify(token, process.env.JWT_SECRET);
return { user };
} catch {
return { user: null };
}
}
});
// Example 2: WebSocket authentication for subscriptions
const server = new ApolloServer({
typeDefs,
resolvers,
subscriptions: {
onConnect: (connectionParams) => {
const token = connectionParams.authToken;
if (!token) throw new Error('Auth required');
const user = jwt.verify(token, SECRET);
return { user };
}
}
});
# Example 3: Schema-level indication of authenticated fields
type Query {
me: User! @auth
publicBooks: [Book!]!
}
type Mutation {
updateProfile(input: UpdateProfileInput!): User! @auth
}
Common Mistakes
- Checking authentication inside resolvers instead of the context function
- Not handling token expiration gracefully with clear error messages
- Using the same token secret across environments
- Ignoring WebSocket authentication for subscriptions
- Storing tokens in client-side local storage without security considerations
Practice
- Implement JWT verification in the context function.
- Add a login mutation that returns a signed token.
- Create protected resolvers that check context.user.
- Implement WebSocket auth for subscription connections.
- Challenge: Build a role-based system with access and refresh tokens.
FAQ
Mini Project
Add JWT authentication to your library API. Implement a login mutation, token verification in context, protected mutations for creating and updating books, and public queries for listing books.
What's Next
Next, you will learn about authorization patterns for controlling access to specific data and operations in GraphQL.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro