Authorization Code
Authorization Code is applicable for integrations involving a highly secure back-channel (backend service) and an insecure front channel (web browser).
In facilitator integration,
- Client is any Facilitator (value-adding service) in the GoBiz application.
- User is the merchant (end-user) of the GoBiz application.
Gojek authorizes both client and user.
- The section below uses terminologies defined in,
- Gojek requires Integrator to provide callback or redirect URIs. Refer RFC 6749: Section 3.1.2 to redirect the user to the client after authorization. :::
The requirements for authorization using the Authorization Code are described in the table given below.
Parameter | Description |
---|---|
Resource Owner | It is the entity that grants access to a protected resource. Value: GoBiz |
Resource Server | It is the server that hosts the protected resources. It accepts and responds to the requests from the client using access tokens. GoBiz API is the resource server. |
Client | It is the web application that accesses the information of the end-user from GoBiz. |
Authorization Server | It is the server that issues access tokens to the client after authenticating the resource owner and obtaining authorization. Value: Gojek |
Integrator | It is the organization that integrates the client with GoBiz. |
User Agent | It is the interface (browser) used to redirect the end-user to Gojek (for authorization) and back to the client. |
Authorization Endpoint | It is used to interact with the resource owner and obtain an authorization grant. The authorization server must first verify the identity of the resource owner. Value: OAUTH_URL/oauth2/auth |
Token Endpoint | It is used by the client to refresh token or obtain an access token by presenting its authorization grant. Value: OAUTH_URL/oauth2/token |
Access Token | It is the token required to access GoBiz APIs. |
ID Token | It is a JSON Web Token (JWT) that contains information about the end-user. |
OAuth 2.0 and OpenID Connect are complex specifications with many security considerations and implications. We recommend you to use a pre-written battle-tested client library that is suitable for the selected language/framework, for developing the client application. You can find a list of libraries at https://oauth.net/code/ (Not maintained by Gojek).
We strongly encourage you to refer RFC 6819: OAuth 2.0 Threat Model and Security Considerations to ensure secure integration. :::
The image below represents the Gojek Authorization Code workflow.
The subsequent sections describe the steps in the workflow and their significance.
Creating Anti-forgery 'state' Token
A state
parameter is required for preventing cross-site request forgery (CSRF) attacks (Refer RFC 6749: Section 10.12). The state
parameter is a unique session token created by the client and holds the state between the client and the user agent (browser). When the user is redirected back to the client after successful authentication and consent, the client should cross-verify the state
token for legitimacy. Thus, the client ensures that the request is coming from legitimate user agent and not a malicious attacker.
state
must be at least 8 characters longstate
must be URL-safe encoded
Sample Code - Python
import os
import hashlib
state = hashlib.sha256(os.urandom(10)).hexdigest()[:16]
Building Query String
The different parameters in the authorization request are described in the table given below.
Parameter | Description | Type | Required |
---|---|---|---|
client_id | It is a unique identifier given to the client by Gojek during generation of the client credentials. | String | Required |
response_type | It should be set to 'code' for authorization code integration. | String | Required |
scope | It is used in authorization code requests to request additional levels of access. The value should be at least openid. | String | Required |
state | It is a unique session token created for preventing CSRF attacks. | String | Required |
redirect_uri | It is the endpoint of the client (backend server). The user is redirected to this URL after authorization. The value should match one of the redirect URI s registered during generation of client credentials. | String | Required |
user_type | It is used to specify the user type of the application. Available values : merchant | String | Required |
nonce | It is a case-sensitive string value that is used to associate a client session with an ID Token and to mitigate replay attacks. | String | Optional |
max_age | It is the maximum age of the authentication session. It forces login if session is older than this value. | Integer | Optional |
ui_locales | It is used to specify the end-user's preferred language and script for the user interface. For example: id or en | String | Optional |
prompt | It is used to prompt the user to re-authenticate or give consents. Available values : none (default), login , and consent . | String | Optional |
Sample URL Param - Query String
https://integration-goauth.gojekapi.com/oauth2/auth?
client_id=my_client_id&
response_type=code&
scope=openid&
redirect_uri=https://client-backend.com/gojek/callback&
state=0ee05c09e1cda629&
user_type=merchant&
prompt=login
The available scopes or access levels are described in the table given below.
Scope | Scope Description |
---|---|
openid | To read basic token info. |
offline | To regenerate access token. |
partner:outlet:read | To read outlet data. |
partner:outlet:write | To edit or update outlet data. |
gofood:catalog:read | To read GoFood menu. |
gofood:catalog:write | To modify GoFood menu. |
gofood:order:read | To read GoFood order data. |
gofood:order:write | To mark an order is ready. |
promo:food_promo:read | To retrieve GoFood promotions. |
promo:food_promo:write | To modify GoFood promotions. |
payment:transaction:read | To read payment transaction. |
payment:transaction:write | To modify payment transaction. |
payment:pop:read | To read payment PoP data. |
mokapos:library:read | To read mokapos libray data. |
mokapos:transaction:read | To read mokapos transaction data. |
mokapos:reporting:read | To read mokapos reporting data. |
mokapos:customer:read | To read mokapos libray data. |
mokapos:checkout:write | To update mokapos checkout data. |
mokapos:salestype:read | To read mokapos sales type data. |
Redirecting User to Gojek Server
The client sends the user to Gojek authorization endpoint (/oauth2/auth
) by redirecting the user agent to the Gojek sign-in page (refer to RFC 6749: Section 1.7). This allows the user to login with Gojek credentials and to authorize the client to access their information on Gojek.
The Gojek sign-in page uses a session cookie to keep track of a user's session in the browser. If Partners need to sign in with a different user, there are solutions available.
- Add
prompt=login
query param to the Gojek sign-in URL. - Use a private or incognito window in the browser.
Processing Authorization Callback
When the Gojek server authenticates the user and authorizes the client to access information, Gojek generates an authorization code. Gojek then redirects the user to redirect_uri
with the code
and the state
originally sent by the client.
On receiving this callback, the client verifies the state
parameter and ensures that the value is same as the one sent earlier.
Sample URL Param - Authorization Callback
https://client-backend.com/gojek/callback?
code=e3q4dqlkjasjdl&
state=0ee05c09e1cda629
Exchanging Code for Access Token & ID Token
The code
returned in the previous step is single-use authorization code and is short-lived (expires in two minutes after receiving the redirection). The client exchanges this code
with Gojek to request an access token and an ID token containing information about the user.
When using the Authorization Code flow, Gojek server creates a session that expires after 9 months. When a session expires, the refresh token no longer works. Partners must ask users to re-authenticate by triggering a new authorization code flow (requesting a new OTP).
A POST
request is sent to the /oauth2/token
endpoint with following parameters in the request body:
Endpoint = OAUTH_URL/oauth2/token
Request Parameters
JSON Attribute | Description | Type | Required |
---|---|---|---|
grant_type | It is the authorization_code as defined in OAuth2 Authorization Code Grant. | String | Required |
code | It is the value received as part of redirection to redirect_uri . | String | Required |
client_id | It is the client identifier issued by GoJek. It should be the same as the one sent during /oauth2/auth . | String | Required |
client_secret | It is the Client Secret issued by GoJek for the client_id . | String | Required |
redirect_uri | It is the redirection URI used during the /oauth2/auth call. | String | Required |
Sample Request
curl -X POST https://integration-goauth.gojekapi.com/oauth2/token \
-u "my_client_id:my_client_secret" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=e3q4dqlkjasjdl" \
-d "redirect_uri=https://client-backend.com/gojek/callback"
When the client credentials are successfully verified, the code
results in a JSON response with the information given in the table below.
Response Parameters
JSON Attribute | Description | Type |
---|---|---|
access_token | It is a token used to access GoBiz API. | String |
id_token | It is an identifier for the token. | String |
expires_in | It is the approximate lifetime (in seconds) of the token that is remaining since receiving the response. | Integer |
token_type | It is the type of token returned. It is always Bearer . | String |
refresh_token | It is a refresh token for renewing access tokens offline (without user). This is present only if the scope contains offline . | String |
Sample Response
{
"access_token": "this_is_the_access_token",
"expires_in": 3600,
"token_type": "Bearer",
"id_token": "this_is_the_token_identifier"
}
Handling Errors
In case of an error, we recommend that you display a user-friendly screen that describes the error, and redirect the user to the login screen so that the user can try to login again.
Error responses and error codes are similar to those defined in RFC 6749: OAuth2.0, except when specified otherwise.
In case of an error during /oauth2/auth
redirection, the error is sent to the client backend as one of the query parameters of the redirect_uri
, as specified in the OAuth 2.0 RFC.
Use Access Token to Access GoBiz API
Access token received in the Exchanging Code for Access Token & ID Token step can be used to access GoBiz APIs by sending the token in the Authorization
header.
For Authorization
header example, see Get All Outlets API.
If you are using an Authorization Code access token, you can only access outlets that accessible by the User. If you access to a different outlet, then it will be rejected.
Identify API only accessible with Authorization Code access token
To identify which API that's only accessible with Authorization Code access token, you can check on the API page and find if it contains go_auth_authorization_code
information.
go_auth_authorization_code(promo:food_promo:write)
means the API is accessible using Authorization Code access token and promo:food_promo:write
scope.
Refresh Token
The Refresh Token grant type lets partners swap a refresh token for a new access token once the access token expires. This keeps partners connected without needing the user to do anything else.
A POST
request is sent to the /oauth2/token
endpoint with following parameters in the request body:
Endpoint = OAUTH_URL/oauth2/token
Request Parameters
JSON Attribute | Description | Type | Required |
---|---|---|---|
grant_type | The value is refresh_token as defined in OAuth2 Refresh Token Grant. | String | Required |
refresh_token | It is an issued refresh token for renewing access tokens offline (without user). | String | Required |
client_id | It is the client identifier issued by GoJek. It should be the same as the one sent during /oauth2/auth . | String | Required |
client_secret | It is the Client Secret issued by GoJek for the client_id . | String | Required |
Sample Request
curl -X POST https://integration-goauth.gojekapi.com/oauth2/token \
-u "my_client_id:my_client_secret" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=dBqRkcp1Aebbc50kXrJLFrh9nHAogNKedsrKtUfwsS0"
When the refresh token are successfully verified, it results in a JSON response with the information given in the table below.
Response Parameters
JSON Attribute | Description | Type |
---|---|---|
access_token | It is a token used to access GoBiz API. | String |
id_token | It is an identifier for the token. | String |
expires_in | It is the approximate lifetime (in seconds) of the token that is remaining since receiving the response. | Integer |
token_type | It is the type of token returned. It is always Bearer . | String |
refresh_token | It is a refresh token for renewing access tokens offline (without user). This is present only if the scope contains offline . | String |
Sample Response
{
"access_token": "this_is_the_access_token",
"expires_in": 3600,
"token_type": "Bearer",
"id_token": "this_is_the_token_identifier"
}
Issues when Refresh Token
There may be failures during the refresh token. Issues listed below requires Partner to re-authenticate.
Issues | Description | Error Condition |
---|---|---|
User is no longer available | If the previous user who entered the OTP is no longer with the outlet, Partners must re-authenticate using a different user from that outlet. | Partners uses correct parameters and refresh token is valid. Gojek system returns 5xx error, even after multiple retries, with message {"error":"server_error","error_description":"The authorization server encountered an unexpected condition that prevented it from fulfilling the request."} |
Session expires after 9 months | Each authorization code flow creates a session that expires after 9 months. Partners must re-authenticate again using a user from that outlet. | Partners uses correct parameters and refresh token is valid. Gojek system returns 4xx error with message {"error":"invalid_grant", "error_description":"The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."} |