# Login ## Tujuan Autentikasi pengguna via LDAP dan mendapatkan JWT Bearer token untuk mengakses API. ## Business Rule - Username dan password divalidasi ke Active Directory (`10.100.1.40`) - Hanya user yang terdaftar di group `Domain Admins`, `Administrators`, atau `Enterprise Admins` yang mendapat `is_admin: true` - JWT diterbitkan dengan TTL dari `API_LDAP_JWT_TTL` (default: 3600 detik) - Setiap percobaan login (berhasil maupun gagal) dicatat di audit log - Maksimum 10 percobaan login per menit per IP ## URL `POST https://console.gisportal.id/api/v1/auth/login` ## HTTP Method `POST` ## Authentication Tidak diperlukan. ## Request Header ``` Content-Type: application/json ``` ## Request Body ```json { "username": "john.doe", "password": "Password123!" } ``` ## Validation | Field | Aturan | |-------|--------| | `username` | required, string, max 100 karakter | | `password` | required, string, max 255 karakter | ## Response Success **HTTP 200** ```json { "data": { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJqb2huLmRvZSIsImlzX2FkbWluIjp0cnVlLCJleHAiOjE3MTk1MDAwMDB9.signature", "token_type": "Bearer", "expires_in": 3600, "auth_type": "ldap_jwt", "user": { "username": "john.doe", "display_name": "John Doe", "is_admin": true } } } ``` ## Response Error **HTTP 401 — Kredensial salah:** ```json { "error": { "code": "invalid_credentials", "message": "Invalid LDAP credentials." } } ``` **HTTP 422 — Validasi gagal:** ```json { "message": "The given data was invalid.", "errors": { "username": ["The username field is required."] } } ``` **HTTP 429 — Rate limit:** ```json { "message": "Too Many Attempts." } ``` ## Status Code | Code | Kondisi | |------|---------| | 200 | Login berhasil | | 401 | Kredensial LDAP salah | | 422 | Validasi request gagal | | 429 | Rate limit (10x/menit) | ## Contoh Request ```bash curl -s -X POST https://console.gisportal.id/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"john.doe","password":"Password123!"}' ``` ## Contoh Response ```json { "data": { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...", "token_type": "Bearer", "expires_in": 3600, "auth_type": "ldap_jwt", "user": { "username": "john.doe", "display_name": "John Doe", "is_admin": true } } } ``` ## Sequence Flow ```mermaid sequenceDiagram Client->>API: POST /auth/login {username, password} API->>LDAP: bind(username, password) LDAP-->>API: success / failed alt Login berhasil API->>LDAP: lookup user groups LDAP-->>API: group list API->>API: issue JWT API->>AuditLog: log api.v1.auth.login API-->>Client: 200 {access_token, user} else Login gagal API->>AuditLog: log api.v1.auth.login.failed API-->>Client: 401 invalid_credentials end ``` ## Database yang Diakses - LDAP (`10.100.1.40`) — read only untuk validasi - `databaselist_audit` — write untuk audit log ## Audit Log | Event | Kondisi | |-------|---------| | `api.v1.auth.login` | Login berhasil | | `api.v1.auth.login.failed` | Login gagal | ## Rate Limit 10 request / menit per IP. Dikonfigurasi via Laravel throttle middleware `throttle:10,1`. ## Idempotent Tidak — setiap request login menghasilkan JWT baru. ## Retry Policy - Jika `401`: jangan retry otomatis. Minta user input ulang. - Jika `429`: tunggu 60 detik. - Jika `500`: retry max 2x dengan backoff 2s. ## Security - Password tidak disimpan di geonet-console, divalidasi langsung ke LDAP - JWT disign dengan `APP_KEY` Laravel - Token dikirim hanya via HTTPS ## Changelog | Tanggal | Perubahan | |---------|-----------| | 2026-06-23 | Dokumentasi dibuat |