Docs
Estimated time: 8 minutes
Difficulty: Intermediate

# API Authentication (Sanctum)

Estimated time: 8 minutes
Difficulty: Intermediate


LaraCoreKit uses Laravel Sanctum for API authentication — lightweight, stateless token authentication perfect for mobile apps, SPAs, and third-party integrations.


How Sanctum Works

1. Client sends email + password to POST /api/tokens
2. Server validates and returns a plaintext token
3. Client stores the token (localStorage, secure cookie, etc.)
4. Client includes the token in the Authorization header
5. Server validates on protected routes

Configuration

Sanctum is pre-configured. Verify in .env:

SANCTUM_STATEFUL_DOMAINS=localhost,127.0.0.1,laracorekit.com

And in config/auth.php, the API guard should use Sanctum:

'guards' => [
    'api' => [
        'driver'   => 'sanctum',
        'provider' => 'users',
    ],
],

Issue a Token

// routes/api.php
Route::post('/tokens', function (Request $request) {
    $request->validate([
        'email'       => 'required|email',
        'password'    => 'required',
        'device_name' => 'required|string',
    ]);

    $user = User::where('email', $request->email)->first();

    if (!$user || !Hash::check($request->password, $user->password)) {
        return response()->json([
            'message' => 'The provided credentials are incorrect.'
        ], 401);
    }

    return response()->json([
        'token' => $user->createToken($request->device_name)->plainTextToken,
        'user'  => $user->only('id', 'name', 'email'),
    ]);
});

Example request:

curl -X POST https://www.laracorekit.com/api/tokens \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"secret","device_name":"My App"}'

Example response:

{
    "token": "1|abc123def456...",
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "[email protected]"
    }
}

Authenticating Requests

# Include token in Authorization header
curl -H "Authorization: Bearer 1|abc123def456..." \
     -H "Accept: application/json" \
     https://www.laracorekit.com/api/user

In JavaScript:

const response = await fetch('/api/user', {
    headers: {
        'Authorization': `Bearer ${token}`,
        'Accept': 'application/json',
    }
});

Protecting Routes

// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user',  fn (Request $r) => $r->user());
    Route::get('/posts', [PostApiController::class, 'index']);
    Route::post('/posts', [PostApiController::class, 'store']);
});

Token Abilities

Issue tokens with restricted abilities:

$token = $user->createToken('mobile-app', ['posts:read', 'posts:write']);

Check abilities in controllers:

if ($request->user()->tokenCan('posts:write')) {
    // Allow write operation
}

Revoking Tokens

// Revoke current token (logout)
$request->user()->currentAccessToken()->delete();

// Revoke all tokens (logout from all devices)
$request->user()->tokens()->delete();

// Revoke a specific token
$user->tokens()->where('name', 'mobile-app')->delete();

Token Expiry

Set token expiry in config/sanctum.php:

'expiration' => 525960, // Minutes (1 year), or null for no expiry

Next Steps

API Endpoints →