LLSR API - Signing and Authenticating REST Requests
Custom HTTP Headers
The LLSR REST API uses HTTP headers to pass authentication information. Under the LLSR authentication scheme, the HTTP headers required are:
X-LLSR-Public
X-LLSR-Sig
X-LLSR-Timestamp
Developers are issued a public key and private key when they register. For request authentication, the X-LLSR-Public element represents
the developer's public key, and is used by the API to identify the requester and to look up the corresponding private key that was used to compute
the signature.
The X-LLSR-Sig element is an HMAC-SHA256 signature of the X-LLSR-Timestamp from the request. The X-LLSR-Sig part of the header
will vary from request to request. If the request signature calculated by the system matches the X-LLSR-Sig included with the request, the
requester will have demonstrated possession of the private key. The request will then be processed under the identity, and with the authority, of the
developer to whom the key was issued.
The element X-LLSR-Timestamp is used to identify when the request was made and to validate the time allowed before the request expires. The
timestamp should be generated at request time, and must be in the standard Unix format (seconds elapsed since the Epoch - midnight of Jan 1, 1970).
PHP Example
$api_url = "https://api.skilouise.com/scanning/validate/";
$season_pass = 'ABC12345';
$public_key = 'MY_PUBLIC_KEY';
$private_key = 'MY_PRIVATE_KEY';
$timestamp = time();
$sig = hash_hmac('sha256', $timestamp, $private_key);
$headers = array(
'X-LLSR-Public: '.$public_key,
'X-LLSR-Sig: '.$sig,
'X-LLSR-Timestamp: '.$timestamp
);
$ch = curl_init($api_url.$season_pass);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, true);
$result = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$json_response = json_decode($result);
JAVA Example (using Unirest)
String publicKeyHeader = MY_PUBLIC_KEY;
Integer timeStampHeader= (int)(System.currentTimeMillis() / 1000L);
String sigHeader = hmacSha256(timeStampHeader.toString(), MY_PRVIATE_KEY);
String url = "https://api.skilouise.com/scanning/validate/";
String seasonPass = "ABC12345";
try
{
HttpResponse<JsonNode> jsonResponse = Unirest.get(url+seasonPass)
.header("accept", "application/json")
.header("x-llsr-public",publicKeyHeader)
.header("x-llsr-timestamp",timeStampHeader.toString())
.header("x-llsr-sig",sigHeader)
.asJson();
if(jsonResponse.getStatus() == 200)
{
//you've got success response code so you can parse the return values.
}
else
{
//an error has occurred. Get the error message.
JSONObject json = jsonResponse.getBody().getObject();
JSONObject error = json.getJSONObject("error");
String errorMessage = error.getString("message");
}
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
public static String hmacSha256(String value, String key)
{
try
{
// Get an hmac_sha1 key from the raw key bytes
byte[] keyBytes = key.getBytes();
SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA256");
// Get an hmac_sha256 Mac instance and initialize with the signing key
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(signingKey);
// Compute the hmac on input data bytes
byte[] rawHmac = mac.doFinal(value.getBytes());
// Convert raw bytes to Hex
byte[] hexBytes = new Hex().encode(rawHmac);
// Covert array of Hex bytes to a String
return new String(hexBytes, "UTF-8");
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
JavaScript Example (using POSTMAN pre-script)
var publicKey = "{public-key}";
var privateKey = "{private-key}";
var requestTimeStamp = new Date().getTime()/1000;
const createHmacString = (ts, privateKey) => {
const key = CryptoJS.enc.Utf8.parse(privateKey)
const timestamp = CryptoJS.enc.Utf8.parse(ts)
const hmac = CryptoJS.enc.Hex.stringify(CryptoJS.HmacSHA256(timestamp, key))
return hmac;
}
const signature = createHmacString(requestTimeStamp, privateKey);
pm.request.headers.add({
key: 'X-LLSR-Public',
value: publicKey
});
pm.request.headers.add({
key: 'X-LLSR-Sig',
value: signature
});
pm.request.headers.add({
key: 'X-LLSR-Timestamp',
value: requestTimeStamp.toString()
});
HTTP Status Codes
The Authentication API uses the following standard HTTP status codes:
200: OK
400: Bad Request
401: Unauthorized
503: Service Unavailable