API Authentication - Integration
Overview
This document describes the integration of authentication in API and how Refresh Token mechanism work to ensure continuous user authentication without forcing re-login after token expiry.
The authentication system uses:
Access Token (short-lived): Attached to each API call for authentication.
Refresh Token (long-lived): Used to obtain a new access token when it expires.
Tokens are typically stored in sessionStorage
.
1. Obtain Access Token
To access protected API endpoints, consumers must include an Authorization
header in every HTTP request. This document explains how to acquire the token and how to include it in your API calls.
For Clients with UI (User Login)
Tokens are issued upon successful login via POST
request with valid credentials.
There are two separate endpoints: one for the Agent Desk and another for the Unified Admin.
Endpoints
POST agent-manager/agent/login
POST unified-admin/keycloakLogin
Request Body
{
"username": "yourUsername",
"password": "yourPassword"
}
Response
{
"statusCode": 200,
"data": {
"token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGY25RNVh4Y...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiAOC1mOTUxLT...",
...
}
}
Save the token
from the response. This is your access token for subsequent requests.
For Non-UI Clients (Backend Services / Integrations)
Use the following POST
endpoint to get token directly from the Keycloak with valid details
Endpoint
POST /auth/realms/{{realm}}/protocol/openid-connect/token
Request Body (x-www-form-urlencoded)
{
'client_id': 'yourClientId',
'client_secret': 'yourClientSecret',
'grant_type': 'password',
'username': 'yourUsername',
'password': 'yourPassword'
}
Response
{
"access_token": "yJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJG...",
"expires_in": 1800,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiAOC1mOTUxLT...",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "00-q89821jw-skjwy82-b773-787w2jhjb",
"scope": "email profile"
}
Save the access_token
from the response. This is your access token for subsequent requests.
2. Use the Token in API Requests
Include the following header with every authenticated API request:
Authorization: Bearer <your_access_token>
Without this header, secured endpoints will return 401 Unauthorized
.
Error Handling
If you receive a 401 Unauthorized
response:
The token may be missing, invalid, or expired.
Ensure you're including the
Authorization
header.If expired, the
HttpInterceptor
catches this response and triggers a refresh token request.Token Refresh Flow:
3. Token Refresh Flow
A separate API call is made with the
refresh_token
.Backend verifies it and returns a new
access_token
.Tokens are updated in
sessionStorage
.The original request is retried with the new
access_token
.
To get the new access token we call the API endpoint with refreshToken.
There are two separate endpoints: one for the Agent Desk and another for the Unified Admin.
Endpoints
POST agent-manager/agent/refresh-token
POST unified-admin/keycloakLogin/refresh-token
Request Body
{
refreshToken: "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIwZjcxNmI1Ny1kZ...."
}
Response
{
"task": "refreshToken",
"msg": "ok",
"statusCode": 200,
"data": {
"status": 200,
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOi..."
}
}
Retry the original request with the new access_token
to get the result.
or Non-UI Clients (Backend Services / Integrations)
Use the following POST
endpoint to get token directly from the Keycloak with valid details
Endpoint
POST /auth/realms/{{realm}}/protocol/openid-connect/token
Request Body (x-www-form-urlencoded)
{
'client_id': 'yourClientId',
'client_secret': 'yourClientSecret',
'grant_type': 'refresh_token',
'refresh_token': 'eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIwZjcxNmI1Ny1kZ...'
}
Response
{
"access_token": "yJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJG...",
"expires_in": 1800,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiAOC1mOTUxLT...",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "00-q89821jw-skjwy82-b773-787w2jhjb",
"scope": "email profile"
}
Save the access_token
from the response.
Retry the original request with the new access_token
to get the result.
Error Handling
If the refresh token is invalid, expired, or rejected:
The user is logged out.
sessionStorage
is cleared.User is redirected to the login page.
Update the lifespan for token:
Keycloak Token Lifespan Configuration