9. Automatically creating third-party client applications¶
9.1. Introduction¶
CargoX Platform provides an /apps/
API endpoint to selected partners (referred to as Suppliers hereon)
that have a need to create client applications for multiple integrations. An example would be an application
which does not run in the cloud but needs to be installed on-premise. It makes sense for each such installation
to have a separate client_id
and client_secret
. This endpoint is suitable for such specific cases.
Each supplier is issued an unique ID and a shared secret. The combination of both is used to requiest new OAuth credentials.
Warning
Please keep these credentials extremely safe. They should not be written down. Ideally, they should be baked into the application itself. If that's not possible and they need to be a part of configuration, make sure that the configuration is encrypted.
If these credentials are compromised an attacker may be able to gain access to all existing instances of your application. CargoX might not be able to detect or influence this.
If you are need to become a software supplier, contact our support at support@cargox.io.
9.2. Authorizing API requests: creating a hash¶
Each request to this API is authorized using your credentials. This is achieved by calculating a timestamped HMAC hash using your issued shared secret.
Message that uniquely defines a client application consists of three parts:
Parameter key
Parameter name
Description
app_id
Instance (Request) ID
The unique request ID. Every instance must use a different ID.
supplier_id
Supplier ID
Your supplier identification code, provided by CargoX.
timestamp
Unix timestamp
Current (Unix) time, truncated down to the last minute.
Attention
app_id
(Application ID) is the unique ID of your request. CargoX will match the app_id
and supplier_id
in
its database and issue only one set of client credentials per combination. This enabled you to call the endpoint
multiple times (e.g. in case of network errors) and be certain you will always get the same result.
How you pick the app_id
is up to you, just make sure they do not overlap. A good ID would be something that does
not change -- e.g. you could either generate it on the first run and save it in the database, or use a combination of
custom prefix and network card's MAC number.
The HMAC
has needs to be calculated using the following formula:
HMAC('{app_id}-{supplier_id}-{timstamp}', '{supplier_secret}')
Here are a couple of examples of how to calculate the hash.
Python
import time import hmac import hashlib APP_ID = get_application_id() SUPPLIER_ID = 'e225d965-205d-4187-b9bd-103f1a54c4d1' SECRET = '3c49474297c6338cce2788ec0ccee44fe38199bd74de3a03802404b2a7b62cfc' timestamp = int(time.time() // 60 * 60) message = '{app_id}-{supplier_id}-{timstamp}'.format(app_id=APP_ID, supplier_id=SUPPLIER_ID, timestamp=timestamp) hash = hmac.new(bytes.fromhex(SECRET), msg=message.encode('utf-8'), digestmod=hashlib.sha256).hexdigest()
PHP
$APP_ID = get_application_id(); $SUPPLIER_ID = 'e225d965-205d-4187-b9bd-103f1a54c4d1'; $SECRET = '3c49474297c6338cce2788ec0ccee44fe38199bd74de3a03802404b2a7b62cfc'; $timestamp = intval(intdiv(time(), 60) * 60); $message = sprintf('%s-%s-%d', $APP_ID, $SUPPLIER_ID, $timestamp); $hash = hash_hmac('sha256', $message, hex2bin($SECRET));
JavaScript
// Define this somewhere within your app, as they do not change const app_id = get_application_id(); const supplier_id = 'e225d965-205d-4187-b9bd-103f1a54c4d1'; const secret = '3c49474297c6338cce2788ec0ccee44fe38199bd74de3a03802404b2a7b62cfc'; let timestamp = Math.floor(Date.now() / 1000 / 60) * 60; // The following code uses CryptoJS: https://cryptojs.gitbook.io/docs/ var hash = CryptoJS.HmacSHA256(`${app_id}-${supplier_id}-${timstamp}`, `${secret}`); var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
Important
To prevent replay attacks, the HMAC
code includes the timestamp. This means that your request will not be valid
indefinitely. More specifically, the server will accept only requests with a timestamp of current and previous minute
(to prevent race conditions where the HMAC
was generated just before the clock rolls around).
In general, this should be a safe margin. If you're running into issues where your hash code validation is faling, make sure you verify your clock is set up correctly first.
9.3. Create a client application¶
To create a new application, call the /apps
endpoint with the following parameters:
Parameter key
Parameter name
Description
app_id
Instance (Request) ID
The unique request ID. Every instance must use a different ID.
supplier_id
Supplier ID
Your supplier identification code, provided by CargoX.
hash
HMAC-calculated hash
Unique hash calculated for this message.
Supplier's email
Email connected with this account. Must be unique for each instance.
Example: To create a new client application, send the following request:
curl --location --request POST 'https://cargox.digital/api/v3/apps/' \
--form 'app_id=supplier-D89FCA8719BDE9F18C' \
--form 'supplier_id=e225d965-205d-4187-b9bd-103f1a54c4d1' \
--form 'hash=4fef62145de199f3351f6f64f32234f6126d77d66f5614a9c5aa4cdf5f8dcdd9' \
--form '[email protected]'
The above request returns would OAuth credentials and application status as a JSON response:
{
"client_id": "rP9wBF8zn8eipsDtYRM5JcnLOazTIl75JXswT20H",
"client_secret": "6819upD3VqLLjvQLVCfTTDKqn4iYBtKdggGZ8km7PYHIWAtpSL0aHuIze3yWOOMBr1AjAdMgvsdoNeA0zgSBLHU2pbKVFkoGidj2x93rsDCWr3nqlgBBTpCEbVaYPaM9",
"allowed_ip_ranges": "",
"status": "active"
}
Note
As explained previously, subsequent requests with the same app_id
and supplier_id
will return existing
credentials without creating a new application.
If your hash
cannot be validated, you will get back a 403 FORBIDDEN
error.
Depending on your agreement with CargoX, the credentials may be enabled automatically. If this is the case,
status will display as "status": "active"
and you can start using your newly assigned credentials straight
away. If the credentials were issued but are not yet confirmed, the status will be shown as "status": "pending"
.
In case of pending
credentials your application should regulary check in with CargoX (see the call bellow)
and inquire about the status of credentials until they switch to active
satte.
9.4. Fetch application OAuth credentials status¶
To fetch existing client application OAuth credentials, make the following request:
curl --location --request GET 'https://cargox.digital/api/v3/apps/supplier-D89FCA8719BDE9F18C/?supplier_id=e225d965-205d-4187-b9bd-103f1a54c4d1&hash=411b0dbf528c65219b92c350db9411651d2e5578a0185fc326dd9a09ab7ae487'
The above request returns OAuth credentials and application status as a JSON response:
{
"client_id": "rP9wBF8zn8eipsDtYRM5JcnLOazTIl75JXswT20H",
"client_secret": "6819upD3VqLLjvQLVCfTTDKqn4iYBtKdggGZ8km7PYHIWAtpSL0aHuIze3yWOOMBr1AjAdMgvsdoNeA0zgSBLHU2pbKVFkoGidj2x93rsDCWr3nqlgBBTpCEbVaYPaM9",
"allowed_ip_ranges": "",
"status": "active"
}