Skip to main content
GraphQL Basics
CHAPTER 15 Beginner

Authentication in GraphQL APIs

Updated: May 13, 2026
25 min read

# CHAPTER 15

Authentication in GraphQL APIs

1. Introduction

We have built a powerful, flexible GraphQL API. But right now, anyone on the internet can query our data. Real-world applications require user accounts, logins, and protected data. In this chapter, we will tackle Authentication—the process of verifying *who* a user is. We will learn how Authentication differs slightly in GraphQL compared to REST, how to use JSON Web Tokens (JWT), and how to pass user identity into your GraphQL Resolvers using the Context object.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Explain how Authentication fits into the GraphQL architecture.
  • Understand the role of HTTP Headers in securing requests.
  • Implement a login Mutation to generate JSON Web Tokens (JWT).
  • Inject the authenticated user into the GraphQL $context object in PHP.

3. Beginner-Friendly Explanation

Imagine a VIP club. Authentication is the bouncer at the front door checking your ID. If you have a valid ID, they give you a wristband. Every time you go to the bar to order a drink (a Query), you don't show your ID again; you just show the bartender your wristband (the Token).

In GraphQL, because there is only one door (the /graphql endpoint), the bouncer stands right in front of it. Before the server even looks at your query, it checks your HTTP Headers for a Token. If the token is valid, the server attaches your "User ID" to a special backpack called the $context. As your query moves through the library (the Resolvers), every librarian (Resolver) can look in the backpack, see who you are, and decide if they should give you the data.

4. Real-World Examples

  • Mobile App Login: A user opens an app and logs in. The GraphQL server verifies the password and sends back a JWT. The app saves this JWT. On every subsequent query (fetching posts, liking photos), the app attaches the JWT to the HTTP request.
  • Public vs Private Data: A blog API allows anyone to query getPosts. But if a user queries myProfile, the resolver checks the $context. If there is no user in the context, it throws a "Not Authenticated" error.

5. The Login Mutation

How do you get the token in the first place? You use a Mutation!

The Schema:

graphql
12345678
type AuthPayload {
  token: String!
  user: User!
}

type Mutation {
  login(email: String!, password: String!): AuthPayload
}

The Query from the Client:

graphql
12345678
mutation UserLogin($email: String!, $pass: String!) {
  login(email: $email, password: $pass) {
    token
    user {
      username
    }
  }
}

*Note: The resolver for login will check the database, verify the password hash, generate a JWT string, and return it.*

6. Sending the Token (The Client Side)

Once the frontend has the token, it must send it with every future query. GraphQL doesn't have a special way to do this; we just use standard HTTP Authorization headers, exactly like REST.

Using Javascript (Fetch API):

javascript
123456789
fetch('https://api.example.com/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    // The wristband!
    'Authorization': 'Bearer YOUR_JWT_TOKEN_HERE'
  },
  body: JSON.stringify({ query: '{ myProfile { name } }' })
})

7. Verifying the Token (The PHP Server Side)

Before we execute the GraphQL schema, our PHP script intercepts the HTTP header, validates the token, and puts the user into the $context.
php
12345678910111213141516171819202122232425
<?php
// 1. Get the HTTP Header
$headers = apache_request_headers();
$token = isset($headers[&#039;Authorization']) ? str_replace('Bearer ', '', $headers['Authorization']) : null;

$currentUser = null;

// 2. Validate the JWT
if ($token) {
    // (Assume decodeJWT returns a user ID if valid)
    $userId = decodeJWT($token); 
    if ($userId) {
        $currentUser = fetchUserFromDatabase($userId);
    }
}

// 3. Inject into the GraphQL Context!
$context = [
    &#039;user' => $currentUser,
    &#039;db' => $pdoConnection
];

// 4. Execute the Query
$result = GraphQL::executeQuery($schema, $query, null, $context, $variables);
?>

8. Using Context in Resolvers

Now, deep inside your GraphQL architecture, your resolvers can instantly know who is making the request!
php
1234567891011
&#039;myProfile' => [
    &#039;type' => $userType,
    &#039;resolve' => function ($root, $args, $context) {
        // Look in the backpack!
        if (!$context[&#039;user']) {
            throw new \Exception("You must be logged in to view this.");
        }
        
        return $context[&#039;user'];
    }
]

9. Best Practices

  • Do Authentication Outside GraphQL: Validating the HTTP header and decoding the JWT should happen in your core PHP/Node application *before* you hand the request to the GraphQL engine.
  • Use standard JWTs: JSON Web Tokens are stateless, secure, and the industry standard for GraphQL authentication.
  • Never store sensitive data in the schema: Never return passwords, password hashes, or salt strings in your GraphQL Schema types.

10. Common Mistakes

  • Putting Login logic in HTTP parameters: Do not pass passwords via GET parameters. Always use a GraphQL POST Mutation over an HTTPS connection.
  • Confusing Authentication with Authorization: *Authentication* is proving who you are (logging in). *Authorization* is proving what you are allowed to do (admin vs user). We will cover Authorization next!

11. Mini Exercises

  1. 1. What HTTP header is standard for sending authentication tokens?
  1. 2. Which of the 4 resolver arguments is used to pass the authenticated user down to all resolvers?

12. Coding Challenges

Challenge 1: Write a mock PHP resolver for a mutation called deleteMyAccount. The resolver should check the $context to ensure the user is logged in. If they are not, throw new \Exception("Unauthorized");. If they are, return true.

13. MCQs with Answers

Question 1

In a typical GraphQL architecture, where is the JWT (token) placed when the client makes a query?

Question 2

How do deeply nested resolvers access the identity of the currently logged-in user?

Question 3

Which operation is used to accept a username and password and return an authentication token?

14. Interview Questions

  • Q: Explain the flow of Authentication in a GraphQL application from the moment the user clicks "Login" to their next subsequent query.
  • Q: Why do we populate the user data into the $context object instead of having every resolver check the HTTP headers themselves?
  • Q: Is GraphQL responsible for Authentication, or is it handled by the HTTP transport layer?

15. FAQs

Q: Can I use traditional Session cookies instead of JWTs with GraphQL? A: Yes! Since GraphQL operates over HTTP, if your browser has an active session cookie, PHP will read it automatically. However, JWTs are preferred for APIs that serve mobile apps or decoupled React/Vue frontends.

16. Summary

In this chapter, we learned how to secure our API. Because GraphQL operates over a single endpoint, we handle Authentication at the HTTP layer, intercepting tokens before the query executes. We use a Mutation to generate these tokens, and the client sends the token back via HTTP Headers. Crucially, we learned how the server validates this token and injects the user's identity into the $context object, allowing every resolver to know exactly who is asking for data.

17. Next Chapter Recommendation

Knowing *who* the user is, is only half the battle. What if an authenticated user tries to delete another user's post? Proceed to Chapter 16: Authorization and Security Best Practices to learn how to enforce permissions, roles, and protect your server from malicious queries.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·