Authentication in Laravel 12 with GraphQL and Sanctum – A Step-by-Step Guide

Author

Kritim Yantra

Apr 11, 2025

Authentication in Laravel 12 with GraphQL and Sanctum – A Step-by-Step Guide

Building secure APIs is crucial for modern web applications. In this guide, we'll implement JWT-less authentication in Laravel 12 using Sanctum (Laravel’s lightweight API auth system) and GraphQL.

By the end, you'll learn:
How Sanctum works (Session-based API auth)
Setting up Sanctum with GraphQL
User Registration & Login with GraphQL
Protecting GraphQL Queries & Mutations

Let’s get started!


1. Why Sanctum for GraphQL?

Sanctum is Laravel’s official package for simple, session-based API authentication. Unlike Passport (OAuth), Sanctum is lightweight and perfect for:

  • SPAs (Vue/React frontends)
  • Mobile apps
  • GraphQL APIs

It uses cookie-based sessions for web authentication and API tokens for mobile.


2. Setting Up Laravel 12 with Sanctum & GraphQL

Step 1: Install Laravel & Required Packages

composer create-project laravel/laravel sanctum-graphql
cd sanctum-graphql

Install Lighthouse (GraphQL) and Sanctum:

composer require nuwave/lighthouse laravel/sanctum

Step 2: Publish Sanctum Config & Migrate

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

Step 3: Configure Sanctum Middleware

Add Sanctum’s middleware to app/Http/Kernel.php:

'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    'throttle:api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

Step 4: Enable CORS (For Frontend Requests)

Update config/cors.php:

'paths' => ['*'],  
'supports_credentials' => true,

3. User Model & GraphQL Schema Setup

Step 1: Create User Model & Migration

php artisan make:model User -m

Update the migration (database/migrations/xxxx_create_users_table.php):

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->string('password');
    $table->timestamps();
});

Run migrations:

php artisan migrate

Step 2: Define GraphQL Schema (graphql/schema.graphql)

type Mutation {
    register(name: String!, email: String! @rules(apply: ["email", "unique:users"]), password: String! @rules(apply: ["min:8"])): User @create
    login(email: String!, password: String!): String
    logout: String @guard
}

type Query {
    me: User @guard
}

type User {
    id: ID!
    name: String!
    email: String!
    created_at: String!
    updated_at: String!
}

4. Implementing Authentication Logic

Step 1: Create a Custom Resolver for Login

Generate a resolver:

php artisan make:graphql AuthResolver

Update app/GraphQL/Resolvers/AuthResolver.php:

<?php

namespace App\GraphQL\Resolvers;

use Illuminate\Support\Facades\Auth;

class AuthResolver
{
    public function login($root, array $args)
    {
        if (Auth::attempt(['email' => $args['email'], 'password' => $args['password']])) {
            $user = Auth::user();
            return $user->createToken('auth_token')->plainTextToken;
        }
        throw new \Error('Invalid credentials.');
    }

    public function logout()
    {
        $user = Auth::user();
        $user->tokens()->delete();
        return 'Logged out successfully!';
    }
}

Step 2: Register Resolver in graphql/schema.graphql

type Mutation {
    login(email: String!, password: String!): String @field(resolver: "App\\GraphQL\\Resolvers\\AuthResolver@login")
    logout: String @guard @field(resolver: "App\\GraphQL\\Resolvers\\AuthResolver@logout")
}

5. Testing Authentication in GraphQL Playground

1. Register a User

mutation {
    register(name: "John Doe", email: "john@example.com", password: "password123") {
        id
        name
    }
}

2. Login & Get Token

mutation {
    login(email: "john@example.com", password: "password123")
}

Response:

{
    "data": {
        "login": "1|abcdef123456..."
    }
}

3. Access Protected Route (me Query)

Add the Authorization header in GraphQL Playground:

{
    "Authorization": "Bearer 1|abcdef123456..."
}

Then run:

query {
    me {
        id
        name
        email
    }
}

4. Logout

mutation {
    logout
}

6. Protecting GraphQL Queries & Mutations

Use the @guard directive to protect routes:

type Query {
    secretData: String @guard
}

7. Conclusion

You’ve successfully implemented GraphQL authentication in Laravel 12 using Sanctum! 🎉

What We Covered:

Sanctum setup for session-based auth
User registration & login with GraphQL
Protected routes using @guard
Token-based authentication

Tags

Laravel Php GraphQL

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Continue with Google

Related Posts

How to Upload Images in Laravel 12: A Step-by-Step Guide
Kritim Yantra Kritim Yantra
Feb 28, 2025
Laravel 12 Multi-Auth System: Implementing Separate Admin and User Tables
Kritim Yantra Kritim Yantra
Feb 28, 2025
Laravel 12 Roles and Permissions Setup: Complete Guide
Kritim Yantra Kritim Yantra
Feb 28, 2025