curl --request POST \
--url https://api.example.com/api/auth/login \
--header 'Content-Type: application/json' \
--data '
{
"username": "<string>",
"password": "<string>"
}
'{
"access_token": "<string>",
"refresh_token": "<string>",
"token_type": "<string>",
"user": {
"user_id": "<string>",
"email": "<string>",
"role": "<string>",
"name": "<string>",
"is_admin": true
},
"expires_in": 123,
"requires_password_change": true,
"session": "<string>",
"username": "<string>",
"message": "<string>",
"status_code": 123,
"detail": "<string>"
}Authenticate users with AWS Cognito and obtain JWT access tokens
curl --request POST \
--url https://api.example.com/api/auth/login \
--header 'Content-Type: application/json' \
--data '
{
"username": "<string>",
"password": "<string>"
}
'{
"access_token": "<string>",
"refresh_token": "<string>",
"token_type": "<string>",
"user": {
"user_id": "<string>",
"email": "<string>",
"role": "<string>",
"name": "<string>",
"is_admin": true
},
"expires_in": 123,
"requires_password_change": true,
"session": "<string>",
"username": "<string>",
"message": "<string>",
"status_code": 123,
"detail": "<string>"
}ADMIN_USER_PASSWORD_AUTH flow with email-based authentication.
Authentication Flow:
[email protected]{
"username": "[email protected]",
"password": "SecureP@ssw0rd"
}
"bearer". Use in Authorization header as Bearer {access_token}.Show User Object
access_token will be emptysession field contains session token for password change/api/auth/complete-password-change with session tokenrequires_password_change is true.requires_password_change is true.{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNI...",
"token_type": "bearer",
"user": {
"user_id": "b7d8f6e4-3a2c-4b9d-8e1f-5c6a7d8e9f0a",
"email": "[email protected]",
"role": "user",
"name": "John Doe",
"is_admin": false
},
"expires_in": 3600
}
{
"access_token": "",
"token_type": "bearer",
"user": {
"user_id": "",
"email": "[email protected]",
"role": "user",
"name": "IGAD User",
"is_admin": false
},
"expires_in": 0,
"requires_password_change": true,
"session": "AYABeE...",
"username": "[email protected]",
"message": "Password change required"
}
{
"detail": "Invalid credentials"
}
NotAuthorizedException
{
"detail": "User not found"
}
UserNotFoundException
{
"detail": "Authentication error: {error_code}"
}
UserNotConfirmedException - Email not verifiedPasswordResetRequiredException - Admin-forced password resetTooManyRequestsException - Rate limit exceeded{
"detail": "Login failed: {error_message}"
}
us-east-1ADMIN_USER_PASSWORD_AUTHCOGNITO_USER_POOL_ID environment variableCOGNITO_CLIENT_ID environment variablebackend/app/tools/auth/routes.py:39
sub → user_idemail → emailname → nameis_admin = email in [
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]",
]
backend/app/tools/auth/routes.py:97
ChallengeName: NEW_PASSWORD_REQUIRED:
FORCE_CHANGE_PASSWORD state (first login or admin reset)session token/api/auth/complete-password-change with:
usernamesessionnew_passwordbackend/app/tools/auth/routes.py:67
curl -X POST https://api.igad.int/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "[email protected]",
"password": "SecureP@ssw0rd"
}'
const response = await fetch('https://api.igad.int/api/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: '[email protected]',
password: 'SecureP@ssw0rd',
}),
})
const data = await response.json()
if (response.ok) {
// Store tokens
localStorage.setItem('accessToken', data.access_token)
localStorage.setItem('refreshToken', data.refresh_token)
// Check for password change required
if (data.requires_password_change) {
// Redirect to password change flow
handlePasswordChange(data.session, data.username)
} else {
// Proceed to dashboard
console.log('Logged in as:', data.user.email)
}
} else {
console.error('Login failed:', data.detail)
}
import requests
response = requests.post(
'https://api.igad.int/api/auth/login',
json={
'username': '[email protected]',
'password': 'SecureP@ssw0rd'
}
)
if response.status_code == 200:
data = response.json()
access_token = data['access_token']
# Use token for authenticated requests
headers = {'Authorization': f'Bearer {access_token}'}
user_response = requests.get(
'https://api.igad.int/api/auth/me',
headers=headers
)
else:
print(f"Login failed: {response.json()['detail']}")
TooManyRequestsException with exponential backoff.
user%40igad.int → [email protected])backend/app/tools/auth/routes.py:44