DEV Community

Churchill Emmanuel
Churchill Emmanuel

Posted on

Two Weeks Stuck on Authentication: My Headless API Journey

Turning my Laravel blog into a Headless CMS API sounded like a simple plan.
Until authentication humbled me.

I’ve been debugging this for over two weeks now, and each day feels like I’m peeling another layer of confusion off the code.

At first, I thought the issue was with tokens. Then middleware. Then Laravel itself.
But as usual, the real problem was somewhere between my assumptions and my logic.

1. The Setup That Started It All

I began with Laravel Sanctum for API authentication.
It looked straightforward at first:

// routes/api.php
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->get('/user', [AuthController::class, 'me']);
Enter fullscreen mode Exit fullscreen mode

The login route worked perfectly — until it didn’t.
Some requests passed, others failed without reason.
At one point, valid tokens were being rejected.

Here’s the login method that caused most of the headaches:

public function login(Request $request)
{
    $request->validate([
        'email' => 'required|email',
        'password' => 'required'
    ]);

    if (!Auth::attempt($request->only('email', 'password'))) {
        return response()->json(['message' => 'Invalid credentials'], 401);
    }

    $user = Auth::user();
    $token = $user->createToken('api_token')->plainTextToken;

    return response()->json([
        'user' => $user,
        'token' => $token
    ]);
}
Enter fullscreen mode Exit fullscreen mode

Looks fine, right?
Except, when I tested it repeatedly, Sanctum started throwing token mismatch errors or expiring tokens too early.

2. The Debugging Spiral

At first, I tried clearing caches.

php artisan config:clear
php artisan cache:clear
php artisan route:clear
Enter fullscreen mode Exit fullscreen mode

That didn’t help.
Then I reinstalled Sanctum.
Still broken.

I even doubted my API routes.
But the actual problem turned out to be with how Sanctum handles SPA vs API tokens.
Sanctum was originally built for SPA authentication using session cookies, not pure token-based APIs.

Once I understood that, things started to click.

3. What Finally Worked

I switched to token-based authentication for full API separation.
In config/sanctum.php, I set:

'stateful' => [],
Enter fullscreen mode Exit fullscreen mode

Then I ensured my frontend (still testing via Postman) sent the right headers:

Authorization: Bearer <token>
Accept: application/json
Enter fullscreen mode Exit fullscreen mode

That single header fixed 60% of my issues.
The rest were logic errors — bad validation, expired tokens, missing guards.

4. Lessons Learned

  • Authentication bugs are not always framework issues. Sometimes it’s how you configured it.
  • Always test endpoints individually in Postman.
  • Read the docs again. Then again. Slowly.
  • Don’t overcomplicate things. Start simple, then layer up.

I haven’t even reached the Next.js frontend yet, but this phase taught me something more valuable than a working API:
Debugging is where developers grow.

It’s not about fixing errors.
It’s about learning to think like your system.

And if you can survive two weeks debugging Laravel auth, trust me — you’ll survive anything.

Top comments (0)