- 
                Notifications
    
You must be signed in to change notification settings  - Fork 2
 
SolarNet API authentication scheme
This document describes the V1 SolarNet authentication scheme. This has been superseded by the V2 scheme. The V1 scheme is still supported, but clients should migrate to the V2 scheme.
SolarNet uses a custom HTTP authentication scheme roughly similar to the Amazon S3 web API scheme. Clients of the API must use a security token pair to authenticate each request using a HMAC+SHA1 digest of specific request headers.
The request must include a HTTP date header, either using the standard HTTP Date header or the custom X-SN-Date header. If X-SN-Date is provided, it will be used in preference to the Date header. The exact date included in HTTP header is included in the message digest so its value must be known by the client. As many browser AJAX fameworks set the Date header automatically, the X-SN-Date can be easier to use.
The value of the request date must match the current date on SolarNetwork at the time the request is made, within a small tolerance value. If the difference between the HTTP header date and the SolarNetwork system date is too large, a HTTP 401 error will be returned with a message along the lines of date skew too large.
The request must include a standard HTTP Authorization header using SolarNetworkWS as the authorization scheme. The authorization value is in the form token:hash where token is a SolarUser generated authorization token and hash is the HMAC+SHA1 hash generated from the token secret and message content (described in detail next), encoded as a Base64 string.
Each request must generate a message out of details included with the request; that message is then used as the input to the HMAC+SHA1 digest algorithm used to authenticate the request. The message consists of the following items, delimited by a newline character such that the last item does not have a newline character added to it (newline character  is 0x0A, or \n in most programming languages):
- HTTP request method in upper-case, e.g. 
GET - Value of 
Content-MD5header (or empty string if none). The value can be either Base64 or hex encoded. - Value of 
Content-Typeheader (or empty string if no content) - Request date, from either a 
X-SN-Dateheader or a standardDateheader, using the patternEEE, dd MMM yyyy HH:mm:ss zzzin the GMT time zone (thezzzvalue must be the literal text GMT) - Request path, including lexicographically sorted request parameters appended after a 
?character and encoded askey=valueand delimited by&. Note the keys and values are not URL encoded. The request parameters must be included regardless of the HTTP method ifapplication/x-www-form-urlencodedencoding is used, for example, aPOSTrequest (see below). 
The request path component of the message digest contains the HTTP request path appended with any URL request parameters, sorted lexicographically by their keys. If the HTTP body is encoded as application/x-www-form-urlencoded, those parameters must be added to the path as well. For example, imagine a HTTP request such as:
POST /solaruser/api/v1/sec/instr/add HTTP/1.1
Host: data.solarnetwork.net
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 100
nodeId=11&topic=SetControlParameter¶meters%5B0%5D.name=/power/switch/1¶meters%5B0%5D.value=1
For the message request path, the POST parameters would be sorted into
nodeId=1parameters[0].name=/power/switch/1parameters[0].value=1topic=SetControlParameter
and appended to the path like this:
/solaruser/api/v1/sec/instr/add?nodeId=11¶meters[0].name=/power/switch/1¶meters[0].value=1&topic=SetControlParameter
Here is an example of a GET request using the SolarNetworkWS authentication scheme:
GET /solaruser/api/v1/sec/instr/viewActive?nodeId=11 HTTP/1.1
Host: data.solarnetwork.net
X-SN-Date: Mon, 23 Sep 2013 03:39:39 GMT
Authorization: SolarNetworkWS a09sjds09wu9wjsd9uy2:IXeexIsjH7beMhxLPU1//1fM9FA=
The raw value of the message content is below (note how lines #2 and #3 are empty):
GET
Mon, 23 Sep 2013 03:39:39 GMT
/solaruser/api/v1/sec/instr/viewActive?nodeId=11
Assuming the message is stored in a variable msg then the Authorization header would be calculated like this, using pseudo code:
token = "a09sjds09wu9wjsd9uy2";          // the SolarNet auth token
secret = "my token secret";              // the secret associated with the SolarNet auth token
msg = "...";                             // calculated via rules above
hash = Base64(HmacSHA1(msg, secret));    // call function to hash message, then Base64 encode
authHeader = "Authorization: SolarNetworkWS " +token + ":" + hash;See https://go.solarnetwork.net/dev/api/ for a jQuery client implementation of the SolarNetworkWS authentication scheme designed to showcase how the API can be used.
Here is some examples on using the SolarNetworkWS authentication scheme. Note that the snippets are greatly simplified, and don't handle the canonicalization rules for arbitrary requests. Notably, the query strings are sorted already, and don't require any URI escaping.
This example shows JavaScript using jQuery and CryptoJS to query data:
// auth tokens provided by user somewhere...
var token = "abc123";
var secret = "def456";
// gather request details
var now = new Date().toUTCString();
var path = "/solarquery/api/v1/sec/datum/query";
var query = "?endDate=2014-02-08&nodeId=1&startDate=2014-02-01&type=Consumption";
// construct the message to digest
var msg = "GET\n";
msg += "\n";
msg += "\n";
msg += now + "\n";
msg += path + query;
// create HMAC+SHA1 digest
var hash = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA1(msg, secret));
$.ajax({
	type: 'GET',
	url: "https://data.solarnetwork.net" + path + query,
	dataType: 'json',
	beforeSend: function(xhr) {
		// set the headers on our request
		xhr.setRequestHeader('X-SN-Date', now);
		xhr.setRequestHeader('Authorization', 'SolarNetworkWS ' + token + ":" + hash);
	}
}).done(function (data) {
	// do something with data object
});This example shows a PHP script that uses curl to query data:
// auth tokens provided by user somewhere...
$token = "abc123";
$secret = "def456";
// gather request details
$now = gmdate('D, d M Y H:i:s \G\M\T');
$path = "/solarquery/api/v1/sec/datum/query";
$query = "?endDate=2014-02-08&nodeId=1&startDate=2014-02-01&type=Consumption";
// construct the message to digest
$msg = "GET\n";
$msg .= "\n";
$msg .= "\n";
$msg .= $now . "\n";
$msg .= $path . $query;
// create HMAC+SHA1 digest
$hash = base64_encode(hash_hmac('sha1', $msg, $secret, true));
$httpHeaders = array(
	"X-SN-Date: " . now,
	"Authorization SolarNetworkWS " . $token . ":" . $hash
);
// execute request using curl
$curlOpts = array(
	CURLOPT_URL        => "https://data.solarnetwork.net" . $path . $query,
	CURLOPT_HTTPHEADER => httpHeaders
);
$curl = curl_init();
curl_setopt_array($curl, $opts);
$data = curl_exec($curl);
curl_close($curl);- SolarNetwork API access
 - SolarNetwork API authentication
 - SolarNetwork API rate limiting
 - SolarNetwork global objects
 - SolarNetwork aggregation
 - SolarFlux API
 - SolarIn API
 - SolarQuery API
 - 
SolarUser API
- SolarUser enumerated types
 - SolarUser datum expire API
 - SolarUser datum export API
 - SolarUser datum import API
 - SolarUser event hook API
 - SolarUser location request API
 - SolarUser Cloud Integrations API
 - SolarUser DIN API
 - SolarUser DNP3 API
 - SolarUser ININ API
 - SolarUser OCPP API
 - SolarUser OSCP API
 - SolarUser Secrets API
 - SolarUser SolarFlux API