OAuth2 Token Endpoint
Overview
The OAuth2 token endpoint is used to generate access tokens required for accessing protected resources. The available grant types include:
authorization_code
refresh_token
client_credentials
urn:ietf:params:oauth:grant-type:jwt-bearer
Base URLs:
- DEV:
https://api.dev.koffi.vn/api
- UAT:
https://api.uat.koffi.vn/api
- Production:
https://uat.koffi.vn/api
Endpoint:
- URL:
/v2/oauth/token
- Method:
POST
- Content-Type:
application/x-www-form-urlencoded
- Headers:
Authorization
:- Depends on grant type authorization will be needed
- JWT bearer token required for
urn:ietf:params:oauth:grant-type:jwt-bearer
grant. - Basic authentication required for
client_credentials
grant.
Parameters:
-
grant_type (required): Defines the OAuth2 grant type to be used. Allowed values are:
authorization_code
refresh_token
client_credentials
urn:ietf:params:oauth:grant-type:jwt-bearer
-
assertion:
- The assertion string when using the JWT bearer grant type.
- Required for JWT Bearer Grant
-
scope (optional): The scopes requested for the token, space-separated. Read scopes for more detail
- Example:
ob.invoices.readonly ob.products.readonly
- Example:
-
tenant_connection_code:
- The tenant code for which the token is requested. Defaults to the client application’s tenant if not provided.
- Required for client_credentials grant
-
code:
- Authorization code
- Required for authorization_code grant type
-
refresh_token:
- Refresh token
- Required for refresh_token grant type
-
redirect_uri:
- Redirect uri used in authorization code flow
- Required for authorization_code and refresh_token grant type
-
code_verifier:
- Code verifier needed for Authorization Code Flow with PKCE
-
client_id:
- Client id is needed for public application (SPA, mobile app...) if authorization header was not used
Grant Types and Usage
1. Client Credentials Grant
- Used by clients to request a token using their client credentials.
- Read Application for more detail how to get
client_id
,client_secret
,tenant_connection_code
. - Each tenant in Koffi has a unique connection code. The client application must provide the corresponding connection code when interacting with a specific tenant.
- Refresh token is not returned in this grant type
Authorization Header:
The Authorization
header for this grant type should contain a basic authentication token, which is a base64 encoded string of client_id:client_secret
.
Request Example:
curl --location --request POST 'https://api.dev.koffi.vn/api/v2/oauth/token' --header 'Authorization: Basic <base64(client_id:client_secret)>' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=client_credentials' --data-urlencode 'scope=ob.invoices.readonly ob.products.readonly' --data-urlencode 'tenant_connection_code=<your_tenant_code>'
Response:
{
"access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 3600,
"scopes": [
"ob.invoices.readonly",
"ob.products.readonly"
]
}
2. Authorization Code Grant
Authorizaion url
- Client application needs to construct suitable authorization url and redirect to that url for authorization process
- Base uri
Authorizaion url parameters
- client_id:
- Required
- Application client id
- redirect_uri:
- Required
- One of the registered redirect uri that had been configured for the application
- scope:
- Optional
- Space-separated requested scopes, only require scopes that had been registered for the application.
- If not given, application'scopes will be used.
- state:
- Random state provide by client application, will be returned to client application after completion
- response_type
- Token response type after completion
- Only code is supported
- code_challenge
- Required for public client application(SPAs, mobile app...)
- PKCE challenge code
- code_challenge_method
- Optional
- Algorithm to use when verify code challenge
- Only S256 is supported
Example authorization code flow
- This is example for confidential client application(application that can hide/store secret key)
- Authorization request
https://id.dev.koffi.vn/auth?client_id=CLIENT_ID&redirect_uri=https://demo.com&state=123456789
- After user successfully login and grant consent Koffi will redirect to client application
https://demo.com?code=GENERATED_CODE&state=123456789
- Client application exchange authorization code for access token and refresh token in back channel using oauth token endpoint
curl --location --request POST 'https://api.dev.koffi.vn/api/v2/oauth/token' --header 'Authorization: Basic <base64(client_id:client_secret)>' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=authorization_code' --data-urlencode 'redirect_uri=https://demo.com' --data-urlencode 'code=GENERATED_CODE'
Example authorization code flow with PKCE
- This is example for public client application(SPAs, mobile app)
- Authorization request
https://id.dev.koffi.vn/auth?client_id=CLIENT_ID&redirect_uri=https://demo.com&state=123456789&code_challenge=Xr4ilOzQ4PCOllhK7l6ORuTz4vQE
- code_challenge in this example is (base64 url encode of(SHA-256(secret)))
- After user successfully login and grant consent Koffi will redirect to client application
https://demo.com?code=GENERATED_CODE&state=123456789
- Client application exchange authorization code for access token and refresh token
curl --location --request POST 'https://api.dev.koffi.vn/api/v2/oauth/token' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'client_id=CLIENT_ID' --data-urlencode 'grant_type=authorization_code' --data-urlencode 'redirect_uri=https://demo.com' --data-urlencode 'code=GENERATED_CODE'
--data-urlencode 'code_verifier=secret'
3. Refresh Token Grant
curl --location --request POST 'https://api.dev.koffi.vn/api/v2/oauth/token' --header 'Authorization: Basic <base64(client_id:client_secret)>' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=refresh_token' --data-urlencode 'refresh_token=REFRESH_TOKEN' --data-urlencode 'redirect_uri=https://demo.com'
4. JWT Bearer Grant
- Used by clients to request a token using their JWT Bearer Grant.
- Read Application for more detail how to get
client_id
,private_key
,public_key
,Keypair_id
. - Use
private_key
andpublic_key
to generate JWT Bearer Grant.
Generate JWT Bearer Grant:
Header
{
"alg": "RS256",
"typ": "JWT",
"kid": "<your Keypair_id>"
}
Payload
{
"sub": "<prefix_impersonate>:<impersonate>",
"iss": "<your client_id>",
"aud": "<environment>",
"iat": <inti_timestamp>,
"exp": <expire_timestamp>
}
NOTE:
prefix_impersonate
: possible values:koffi.user.email
orkoffi.user.id
- if
prefix_impersonate
iskoffi.user.email
thenimpersonate
isemail
of the user you want to represent - if
prefix_impersonate
iskoffi.user.id
thenimpersonate
isid
of the user you want to represent
data = base64(Header) + "." + base64(Payload)
JWT Bearer Grant = data + "." + RSASHA256(data)
Request Example:
curl --location --request POST 'https://api.dev.koffi.vn/api/v2/oauth/token' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' --data-urlencode 'scope=ob.invoices.readonly ob.products.readonly' --data-urlencode 'assertion=<your JWT Bearer Grant>'
Response:
{
"access_token": "eyJhbGciOi...",
"token_type": "Bearer",
"expires_in": 3600,
"scopes": [
"ob.invoices.readonly",
"ob.products.readonly"
]
}
Revoke token
- Only support revoke refresh token
curl --location --request POST 'https://api.dev.koffi.vn/api/v2/oauth/revoke?token=TOKEN'
Common Authentication Error
Error response
In case of an error, the response will have an HTTP status code other than 200, with the following format
{
"code": "error_code",
"message": "error_message"
}
Error code
- EOAU401: Unauthorized
- EOAU201: Invalid grant type
- EOAU202: JWT Bearer Grant requires assertion
- EOAU203: JWT Bearer Grant assertion invalid or expired
- EOAU204: JWT Bearer Grant assertion client id (iss) is required (iss)
- EOAU205: JWT Bearer Grant assertion key id (kid) is required
- EOAU206: JWT Bearer Grant assertion key id (kid) is invalid
- EOAU207: JWT Bearer Grant assertion audience (aud) is required
- EOAU208: JWT Bearer Grant assertion user not found (sub)
- EOAU209: Authorization header missing or invalid
- EOAU210: Authorization code missing, invalid or expired
- EOAU211: Redirect uri missing or invalid
- EOAU212: Refresh token missing or invalid
- EOAU213: Client id missing or invalid
- EOAU214: Missing code verifier
- EOAU215: Invalid tenant connection code or client application has no access to target tenant
- EOAU100: Invalid authorize request info
- EOAU101: Invalid scope
<invalid-scopes>
- EOAU102: User does not belong to application's organization
- EOAU103: Application is not published yet
- EOAU104: Public application requires code challenge