Authentication
The CPR backend uses Laravel Sanctum for API token authentication.
How It Works
- User sends credentials to
POST /api/v1/auth/login - Server validates credentials and returns an API token
- Client includes the token in subsequent requests via
Authorization: Bearer <token>header - Sanctum middleware validates the token on protected routes
Auth Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST | /api/v1/auth/login | Login and receive token |
POST | /api/v1/auth/logout | Revoke current token |
GET | /api/v1/auth/profile | Get authenticated user profile |
PUT | /api/v1/auth/profile | Update profile |
POST | /api/v1/auth/switch-branch | Switch active branch |
GET | /api/v1/auth/branches | List accessible branches |
POST | /api/v1/auth/reset-code | Request password reset code |
POST | /api/v1/auth/verify-code | Verify reset code |
POST | /api/v1/auth/reset-password | Reset 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: 1Configuration
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 defaultEnvironment Variables
env
SANCTUM_STATEFUL_DOMAINS=localhost:3000,localhost:5173
SESSION_DOMAIN=localhost
API_TOKEN_EXPIRY=1440 # Optional: token expiry in minutesPassword Reset Flow
The password reset uses a code-based flow (not link-based):
POST /api/v1/auth/reset-code- Sends a numeric code to the user's emailPOST /api/v1/auth/verify-code- Validates the codePOST /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_ROUNDSenvironment variable
Middleware Stack
Protected routes use this middleware chain:
throttle:api → auth:sanctum → [branch.context] → [permission:X]auth:sanctum- Validates the bearer tokenbranch.context- Resolves and validates branch access (on branch-scoped routes)permission:X- Checks Spatie permissions (on admin routes)