Skip to content

Authentication in GraphQL — Complete Guide

DodaTech Updated 2026-06-28 3 min read

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

  1. Implement JWT verification in the context function.
  2. Add a login mutation that returns a signed token.
  3. Create protected resolvers that check context.user.
  4. Implement WebSocket auth for subscription connections.
  5. Challenge: Build a role-based system with access and refresh tokens.

FAQ

Should I authenticate at the transport or application layer?

Authenticate at the transport layer in the context function. This keeps resolvers clean and ensures consistent auth across all operations.

How do I handle token expiration?

Return a specific error code for expired tokens. Clients refresh the token and retry. Use formatError to standardize the response.

Can I use session-based auth with GraphQL?

Yes. If your web framework uses sessions, the session data is available in req.session and can be added to context.

How do I authenticate public and private operations?

Public operations need no auth. Private operations check context.user. Use directives or wrapper functions to mark protected operations.

What is the best way to pass tokens from client?

Use the Authorization header with Bearer scheme for queries and mutations. Use connectionParams for WebSocket subscriptions.

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