API Authentication

Complete guide to authenticating with LaraDashboard's REST API using Laravel Sanctum tokens and managing API credentials.

API Authentication

LaraDashboard's REST API uses Laravel Sanctum for token-based authentication. This guide covers obtaining tokens, making authenticated requests, and managing API access.

Overview

Authentication Method

The API uses Bearer token authentication via Laravel Sanctum:

Authorization: Bearer <your-token>

Base URL

All API endpoints are prefixed with:

https://yourdomain.com/api/v1/

Obtaining Tokens

Login Endpoint

Exchange credentials for an API token:

POST /api/auth/login
Content-Type: application/json

{
    "email": "user@example.com",
    "password": "your-password"
}

Response (200 OK):

{
    "access_token": "1|abc123xyz789...",
    "token_type": "Bearer",
    "expires_at": "2024-02-15T10:30:00.000000Z",
    "user": {
        "id": 1,
        "email": "user@example.com",
        "name": "John Doe"
    }
}

Response (401 Unauthorized):

{
    "message": "Invalid credentials",
    "error": "authentication_failed"
}

Token Expiration

Tokens expire based on configuration (default: 7 days). Check expires_at in the response.

Making Authenticated Requests

Using the Token

Include the token in the Authorization header:

GET /api/v1/users
Authorization: Bearer 1|abc123xyz789...
Content-Type: application/json
Accept: application/json

Example with cURL

# Get users list
curl -X GET "https://yourdomain.com/api/v1/users" \
     -H "Authorization: Bearer 1|abc123xyz789..." \
     -H "Accept: application/json"

# Create a post
curl -X POST "https://yourdomain.com/api/v1/posts" \
     -H "Authorization: Bearer 1|abc123xyz789..." \
     -H "Content-Type: application/json" \
     -H "Accept: application/json" \
     -d '{"title": "New Post", "content": "Post content"}'

Example with JavaScript

// Using fetch
const response = await fetch('https://yourdomain.com/api/v1/users', {
    method: 'GET',
    headers: {
        'Authorization': `Bearer ${token}`,
        'Accept': 'application/json',
        'Content-Type': 'application/json',
    },
});

const data = await response.json();

Example with PHP

use Illuminate\Support\Facades\Http;

$response = Http::withToken($token)
    ->get('https://yourdomain.com/api/v1/users');

$users = $response->json('data');

Token Management

Get Current User

Retrieve the authenticated user's information:

GET /api/auth/user
Authorization: Bearer <token>

Response:

{
    "id": 1,
    "email": "user@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "roles": ["admin"],
    "permissions": ["users.view", "posts.create", ...]
}

Logout (Revoke Current Token)

Invalidate the current token:

POST /api/auth/logout
Authorization: Bearer <token>

Response (204 No Content)

Revoke All Tokens

Invalidate all tokens for the user:

POST /api/auth/revoke-all
Authorization: Bearer <token>

Response:

{
    "message": "All tokens revoked successfully",
    "revoked_count": 5
}

Token Abilities (Scopes)

Creating Tokens with Abilities

Tokens can be created with specific abilities (scopes):

// In your application
$token = $user->createToken('api-token', [
    'read',
    'write',
    'delete'
]);

Available Abilities

Ability Description
read Read access to resources
write Create and update resources
delete Delete resources
admin Administrative actions
* Full access

Checking Abilities

The API checks token abilities before allowing actions:

// Server-side check
if ($request->user()->tokenCan('write')) {
    // Allow write operation
}

Error Responses

401 Unauthorized

No token or invalid token:

{
    "message": "Unauthenticated.",
    "error": "unauthenticated"
}

403 Forbidden

Valid token but insufficient permissions:

{
    "message": "This action is unauthorized.",
    "error": "forbidden"
}

419 Token Expired

Session/token expired:

{
    "message": "Session expired. Please login again.",
    "error": "token_expired"
}

Rate Limiting

Default Limits

User Type Limit
Authenticated 120 requests/minute
Unauthenticated 30 requests/minute

Rate Limit Headers

Responses include rate limit information:

X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
X-RateLimit-Reset: 1705312800

429 Too Many Requests

When rate limited:

{
    "message": "Too Many Attempts.",
    "error": "rate_limit_exceeded",
    "retry_after": 45
}

Security Best Practices

Token Storage

DO:

  • Store tokens securely (encrypted storage, secure cookies)
  • Use HTTPS for all API calls
  • Implement token refresh before expiration

DON'T:

  • Store tokens in localStorage (XSS vulnerable)
  • Include tokens in URLs
  • Log tokens in plain text
  • Share tokens between environments

Token Rotation

Implement token refresh:

async function apiRequest(url, options) {
    let response = await fetch(url, {
        ...options,
        headers: {
            ...options.headers,
            'Authorization': `Bearer ${getToken()}`,
        },
    });

    if (response.status === 401) {
        // Token expired, try to refresh
        await refreshToken();
        response = await fetch(url, {
            ...options,
            headers: {
                ...options.headers,
                'Authorization': `Bearer ${getToken()}`,
            },
        });
    }

    return response;
}

CORS Configuration

Configure allowed origins in config/cors.php:

return [
    'paths' => ['api/*'],
    'allowed_origins' => ['https://yourfrontend.com'],
    'allowed_methods' => ['*'],
    'allowed_headers' => ['*'],
    'exposed_headers' => ['X-RateLimit-Limit', 'X-RateLimit-Remaining'],
    'max_age' => 0,
    'supports_credentials' => true,
];

Testing Authentication

Using Postman

  1. Create a new request
  2. Go to Authorization tab
  3. Select Bearer Token
  4. Paste your token
  5. Send request

Using Insomnia

  1. Create a new request
  2. Click Auth dropdown
  3. Select Bearer Token
  4. Enter token value

Automated Testing

use Laravel\Sanctum\Sanctum;

public function test_authenticated_user_can_access_api()
{
    $user = User::factory()->create();

    Sanctum::actingAs($user, ['read', 'write']);

    $response = $this->getJson('/api/v1/users');

    $response->assertOk();
}

Troubleshooting

Token Not Working

  1. Check token format: Bearer <token> (with space)
  2. Verify token hasn't expired
  3. Ensure HTTPS is used
  4. Check token wasn't revoked

CORS Errors

  1. Verify origin is in allowed list
  2. Check preflight (OPTIONS) requests work
  3. Ensure credentials mode matches config

401 on All Requests

  1. Check Sanctum middleware is applied
  2. Verify personal_access_tokens table exists
  3. Check APP_URL matches request origin

API Documentation

OpenAPI/Swagger

Access auto-generated API documentation:

GET /api/docs          # Interactive documentation
GET /api.json          # OpenAPI specification

Next Steps

/