Kritim Yantra
Apr 11, 2025
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!
Sanctum is Laravel’s official package for simple, session-based API authentication. Unlike Passport (OAuth), Sanctum is lightweight and perfect for:
It uses cookie-based sessions for web authentication and API tokens for mobile.
composer create-project laravel/laravel sanctum-graphql
cd sanctum-graphql
Install Lighthouse (GraphQL) and Sanctum:
composer require nuwave/lighthouse laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
Add Sanctum’s middleware to app/Http/Kernel.php
:
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
Update config/cors.php
:
'paths' => ['*'],
'supports_credentials' => true,
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
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!
}
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!';
}
}
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")
}
mutation {
register(name: "John Doe", email: "john@example.com", password: "password123") {
id
name
}
}
mutation {
login(email: "john@example.com", password: "password123")
}
Response:
{
"data": {
"login": "1|abcdef123456..."
}
}
me
Query)Add the Authorization header in GraphQL Playground:
{
"Authorization": "Bearer 1|abcdef123456..."
}
Then run:
query {
me {
id
name
email
}
}
mutation {
logout
}
Use the @guard
directive to protect routes:
type Query {
secretData: String @guard
}
You’ve successfully implemented GraphQL authentication in Laravel 12 using Sanctum! 🎉
✔ Sanctum setup for session-based auth
✔ User registration & login with GraphQL
✔ Protected routes using @guard
✔ Token-based authentication
Transform from beginner to Laravel expert with our personalized Coaching Class starting June 23, 2025. Limited enrollment ensures focused attention.
1-hour personalized coaching
Build portfolio applications
Industry-standard techniques
Interview prep & job guidance
Complete your application to secure your spot
Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.
No comments yet. Be the first to comment!
Please log in to post a comment:
Sign in with Google