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

LIVE MENTORSHIP ONLY 5 SPOTS

Laravel Mastery
Coaching Class Program

KritiMyantra

Transform from beginner to Laravel expert with our personalized Coaching Class starting June 23, 2025. Limited enrollment ensures focused attention.

Daily Sessions

1-hour personalized coaching

Real Projects

Build portfolio applications

Best Practices

Industry-standard techniques

Career Support

Interview prep & job guidance

Total Investment
$200
Duration
30 hours
1h/day

Enrollment Closes In

Days
Hours
Minutes
Seconds
Spots Available 5 of 10 remaining
Next cohort starts:
June 23, 2025

Join the Program

Complete your application to secure your spot

Application Submitted!

Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.

What happens next?

  • Confirmation email with program details
  • WhatsApp message from our team
  • Onboarding call to discuss your goals

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in 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