Welcome to the OpenCities help centre. Search for what you're after, or browse the categories.
Can't find what you're looking for? Submit a support ticket and we'll be in touch.

Follow

HMAC Authentication

avatar of OpenCities Product Team

OpenCities Product Team

Last updated

This is a Developer task

The Rest API uses HMAC as an authentication mechanism. The authentication header should be sent with every request with the schema set to hmac followed by the parameters and signature as below.

Authorization: hmac <<AppId>>:<<Signature Hash Base64 Encoded>>:<<nounce>>:<<Request unix time (total seconds from 1/1/1970)>>

Signature Hash

The signature hash is generated using the HMACSHA256 hashing algorithm to hash a string, constructed by combining:

  • AppId
  • HTTP method
  • Request URL (must be URL encoded and converted to lower case)
  • Request timestamp (total seconds from 1/1/1970)
  • Nounce (a random string with alphabets and numbers)
  • Base64 encoded request body

JS Client

Below is a JS code block which can be used to construct the authentication string.

function createAuthenticationHeader(appId, method, url, body, hmacKey)
{        
	var nounce = generateNounce();        
	var timestamp = Math.floor(Date.now() / 1000);        
	var message = appId + method + encodeURIComponent(url).toLowerCase() + timestamp + nounce + (body ? btoa(body) : '');        
	var signature = CryptoJS.HmacSHA256(message, hmacKey).toString(CryptoJS.enc.Base64);        
	return 'hmac ' + appId + ':' + signature + ':' + nounce + ':' + timestamp;
}

Note: this code uses encryption modules from CryptoJS libraries to generate the hash.

C# Client

Below is a C# code block which can be used to construct the authentication string.

protected static HttpResponseMessage Send(HttpRequestMessage request, string AppId, string ApiKey)
{
	string requestContentBase64String = string.Empty;

	string requestUri = HttpUtility.UrlEncode(request.RequestUri.AbsoluteUri.ToLower());

	string requestHttpMethod = request.Method.Method;

	//Calculate UNIX time
	DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc);
	TimeSpan timeSpan = DateTime.UtcNow - epochStart;
	string requestTimeStamp = Convert.ToUInt64(timeSpan.TotalSeconds).ToString();

	//create random nonce for each request
	string nonce = Guid.NewGuid().ToString("N");

	//Checking if the request contains body, usually will be null with HTTP GET and DELETE
    if (request.Content != null)
    {
        byte[] content = Encoding.UTF8.GetBytes(await request.Content.ReadAsStringAsync());
        requestContentBase64String = Convert.ToBase64String(content);
    } //Creating the raw signature string string signatureRawData = String.Format("{0}{1}{2}{3}{4}{5}", AppId, requestHttpMethod, requestUri, requestTimeStamp, nonce, requestContentBase64String); var secretKeyByteArray = Encoding.UTF8.GetBytes(ApiKey); byte[] signature = Encoding.UTF8.GetBytes(signatureRawData); using (HMACSHA256 hmac = new HMACSHA256(secretKeyByteArray)) { byte[] signatureBytes = hmac.ComputeHash(signature); string requestSignatureBase64String = Convert.ToBase64String(signatureBytes); request.Headers.Authorization = new AuthenticationHeaderValue("hmac", string.Format("{0}:{1}:{2}:{3}", AppId, requestSignatureBase64String, nonce, requestTimeStamp)); } return request.CreateResponse(); }

Client CodeGen

The API model is described using Swagger's JSON specification. The spec file can be downloaded from the admin application at '/includes/swagger/apispec.json'. This file can also be used with Swagger CodeGen to autogenerate the base client code for consuming the API.

Was this article helpful?
0 out of 0 found this helpful