Authentication API¶
Authentication is handled by django-allauth in headless mode, wrapped in django-ninja-extra controllers. All auth endpoints are under /api/v1/auth/.
Session Management¶
Get Session¶
Check the current authentication state.
Response (authenticated):
{
"status": 200,
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "admin@acme.com",
"username": null
},
"method": {
"method": "password",
"at": 1706817600,
"email": "admin@acme.com"
}
}
}
Response (unauthenticated):
Login¶
Headers:
Request body:
Response (200):
{
"status": 200,
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "admin@acme.com"
},
"method": {
"method": "password",
"at": 1706817600,
"email": "admin@acme.com"
}
}
}
On success, the server sets a sessionid httpOnly cookie.
Warning
Login is rate-limited to 10 requests per minute per IP address.
Logout¶
Headers:
Response: 200 OK
Clears the session cookie.
Signup¶
Request body:
Response: 200 OK with user data. If email verification is required (ACCOUNT_EMAIL_VERIFICATION = "mandatory"), the user must verify their email before logging in.
Re-authenticate¶
For sensitive operations that require recent authentication.
Request body:
Password Management¶
Request Password Reset¶
Request body:
Response: 200 OK (always returns 200, even if email is not found, to prevent enumeration).
Warning
Rate-limited to 5 requests per minute.
Validate Reset Key¶
Response (200): Key is valid.
Response (400): Key is invalid or expired.
Reset Password¶
Request body:
Change Password¶
Requires an authenticated session.
Request body:
Email Verification¶
List Email Addresses¶
Response:
Add Email Address¶
Request body:
Verify Email¶
Request body:
Mark Email as Primary¶
Request body:
Login Code¶
For passwordless login flows.
Request Login Code¶
Request body:
Confirm Login Code¶
Request body:
Auth Configuration¶
Get the available authentication methods and configuration.
Response:
Current User¶
Get Current User¶
Returns the authenticated user with their tenant role and RBAC permissions.
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "admin@acme.com",
"first_name": "Admin",
"last_name": "User",
"tenant_role": "admin",
"permissions": [
{"action": "list", "resource": "borrowers"},
{"action": "show", "resource": "borrowers"},
{"action": "create", "resource": "borrowers"},
{"action": "edit", "resource": "borrowers"},
{"action": "list", "resource": "loans"},
{"action": "show", "resource": "loans"},
{"action": "create", "resource": "loans"},
{"action": "approve", "resource": "loans"},
{"action": "*", "resource": "ledger_accounts"},
{"type": "deny", "action": "show", "resource": "borrowers", "record": {"ssn": true}}
]
}
The permissions array follows the react-admin RBAC format:
{"action": "list", "resource": "borrowers"}--- allow listing borrowers{"action": "*", "resource": "*"}--- superadmin wildcard{"type": "deny", ...}--- deny a specific action (e.g., SSN field access)
Permission sources (merged):
- Tenant role mapping --- from
common/rbac.py - Django auth permissions --- from Group/Permission assignments
- Object-level grants --- from django-guardian
CSRF Token Flow¶
1. GET /api/v1/auth/session
← Set-Cookie: csrftoken=abc123
2. POST /api/v1/auth/login
→ Cookie: csrftoken=abc123
→ X-CSRFToken: abc123
→ {"email": "...", "password": "..."}
← Set-Cookie: sessionid=xyz789
3. POST /api/v1/loans
→ Cookie: sessionid=xyz789; csrftoken=abc123
→ X-CSRFToken: abc123
→ {"borrower_id": "...", ...}
See Also¶
- API Overview --- Base URL, pagination, error format
- Users API --- User management endpoints
- Multi-Tenancy --- Domain routing and tenant resolution