-
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-MD5
header (or empty string if none). The value can be either Base64 or hex encoded. - Value of
Content-Type
header (or empty string if no content) - Request date, from either a
X-SN-Date
header or a standardDate
header, using the patternEEE, dd MMM yyyy HH:mm:ss zzz
in the GMT time zone (thezzz
value must be the literal text GMT) - Request path, including lexicographically sorted request parameters appended after a
?
character and encoded askey=value
and 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-urlencoded
encoding is used, for example, aPOST
request (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=1
parameters[0].name=/power/switch/1
parameters[0].value=1
topic=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 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 SolarFlux API