Authentication mechanism
We use HMAC authentication which has been widely used by Amazon and Google to grant access to many of their APIs.
Base URL
https://tv-staging.trustingsocial.com/api
1. API Access Key
A pair of:
Access Key ID: a unique identifier (UUID) of the API access key.
Access Key Secret: a secret key that will be used to sign the requests.
TrustVision team will provide an access key pair for each customers before integration.
2. Client signs a request
Two required headers:
X-TV-Timestamp: Current timestamp in RFC3339 format.
- Example:
2019-04-21T18:00:15+07:00
- Example:
Authorization: Header value format
TV {AccessKeyID}:{Signature}.- Example:
TV a0ce69ea-cbf7-49cc-ab47-6381ed7c5cf8:Rm4qG9YHhDaaUdwQlKqPjuzgQkyobDFVfZAZrlEVFwc=
- Example:
Where
AccessKeyID: provided by TrustVision.Signature: a Base64 encoded HMAC SHA256 hash of the StringToSign, refer to the following pseudo code:
# Pseudo code
StringToSign = HttpMethod + "\n" + UrlPath + "\n" + Timestamp
# HttpMethod: such as `POST`, `GET`, `PUT`, `PATCH`, `DELETE`
# UrlPath: relative route path of the resource (exclude the domain). Example: `/v1/images`
# Timestamp: the time of the request in RFC3339 format. The client must also
send this timestamp with the request in the `X-TV-Timestamp` header.
Signature = Base64(HmacSha256(AccessKeySecret, Utf8EncodingOf(StringToSign)))
Advanced: Hash the Content using MD5 and add to StringToSign
StringToSign = HttpMethod + "\n" + UrlPath + "\n" + Timestamp + "\n" + ContentMD5;
# ContentMD: hash whole JSON content
Note: When we use content MD5 hashing, we have to AES-256 encrypt JSON content to new JSON structure first
{
"payload": string, // AES-256 encrypted content
}
Please contact the administrator for more detail.
Reference: Base64 encoded HMAC SHA256 hash (in different languages)
Sample Signature generation code:
// Provided by TV
accessKeyId = "<YOUR ACCESS KEY>";
accessKeySecret = "<YOUR SECRET>";
// Request info
method = "POST"
urlPath = "/v1/images"
rfc3339date = "2019-04-21T18:00:15+07:00"
// Create signature
var stringToSign = method + "\n" + urlPath + "\n" + rfc3339date;
var signature = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(stringToSign, accessKeySecret););
// Send request
var myHeaders = new Headers();
myHeaders.append("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
myHeaders.append("Authorization", "TV " + accessKeyId + ":" + signature);
myHeaders.append("X-TV-Timestamp", rfc3339date);
var formdata = new FormData();
formdata.append("file", fileInput.files[0], "file");
formdata.append("label", "portrait");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: formdata,
redirect: 'follow'
};
fetch("https://tv-staging.trustingsocial.com/api/v1/images", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
Try verifying Signature using online tool, check the Base64 result to compare with your own computation.
3. Send request
Sample request detail:
| Key | Value |
|---|---|
| Timestamp | 2019-04-21T18:00:15+07:00 |
| HTTP Verb | POST |
| Staging endpoint | https://tv-staging.trustingsocial.com/api |
| Path | /v1/images |
Sample code:
curl -X POST \
https://tv-staging.trustingsocial.com/api/v1/images \
-H 'Authorization: TV <YOUR ACCESS KEY>:<CREATED SIGNATURE>' \
-H 'X-TV-Timestamp: 2019-04-21T18:00:15+07:00' \
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \
-F file=@/images/portrait.jpg \
-F label=portrait
4. Server verifies the request signature
To verify the signature, the server first takes the request timestamp from
X-TV-Timestamp header, compares it with current timestamp of the server.
If the difference between 2 timestamps is more than 15 minutes, it will
reject the request and return RequestTimeTooSkewed error to the client.
The intention of this restriction is to limit the possibility that
intercepted requests could be replayed by an adversary.
If the timestamp is within the limit, the server will then parse value from
Authorization header to get AccessKeyID and Signature (separated by :).
It looks up AccessKeyID to get the corresponding AccessKeySecret.
After that, the server uses the request timestamp to generate the string to
sign, and use the AccessKeySecret to creates the signature with the same
method as described before.
Finally, the request is authorized if the generated signature matches the request signature.