Skip to content

Authentication

The CPR backend uses Laravel Sanctum for API token authentication.

How It Works

  1. User sends credentials to POST /api/v1/auth/login
  2. Server validates credentials and returns an API token
  3. Client includes the token in subsequent requests via Authorization: Bearer <token> header
  4. Sanctum middleware validates the token on protected routes

Auth Endpoints

MethodEndpointDescription
POST/api/v1/auth/loginLogin and receive token
POST/api/v1/auth/logoutRevoke current token
GET/api/v1/auth/profileGet authenticated user profile
PUT/api/v1/auth/profileUpdate profile
POST/api/v1/auth/switch-branchSwitch active branch
GET/api/v1/auth/branchesList accessible branches
POST/api/v1/auth/reset-codeRequest password reset code
POST/api/v1/auth/verify-codeVerify reset code
POST/api/v1/auth/reset-passwordReset password with code

Login Example

Request:

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

{
    "username": "admin",
    "password": "password"
}

Response:

json
{
    "message": "Login successful",
    "data": {
        "user": { ... },
        "token": "1|abc123...",
        "branches": [...]
    }
}

Using the Token

Include the token in all authenticated requests:

http
GET /api/v1/patients
Authorization: Bearer 1|abc123...
X-Branch-Id: 1

Configuration

Sanctum (config/sanctum.php)

php
'stateful' => [
    'localhost',
    'localhost:3000',
    '127.0.0.1',
    '127.0.0.1:8000',
],
'guard' => ['web'],
'expiration' => null,  // Tokens don't expire by default

Environment Variables

env
SANCTUM_STATEFUL_DOMAINS=localhost:3000,localhost:5173
SESSION_DOMAIN=localhost
API_TOKEN_EXPIRY=1440  # Optional: token expiry in minutes

Password Reset Flow

The password reset uses a code-based flow (not link-based):

  1. POST /api/v1/auth/reset-code - Sends a numeric code to the user's email
  2. POST /api/v1/auth/verify-code - Validates the code
  3. POST /api/v1/auth/reset-password - Sets the new password

This is implemented via the Pipeline pattern:

  • ResetCode Pipeline: ValidateUserExists → GenerateResetCode → StoreResetCode → SendResetCodeEmail
  • ResetPassword Pipeline: FetchUser → FindValidCode → UpdatePassword → MarkCodeAsUsed

Password Hashing

  • Algorithm: bcrypt
  • Rounds: 12 (production), 4 (testing for speed)
  • Configured via BCRYPT_ROUNDS environment variable

Middleware Stack

Protected routes use this middleware chain:

throttle:api → auth:sanctum → [branch.context] → [permission:X]
  • auth:sanctum - Validates the bearer token
  • branch.context - Resolves and validates branch access (on branch-scoped routes)
  • permission:X - Checks Spatie permissions (on admin routes)

CPR - Clinical Patient Records