Hi,
Like a few others in the community, I wrote my first SmartApp without using node.js. As I understand it, one of the reasons for moving away from groovy was to give developers the flexibility to use “any language” to implement the SmartApp. Any language that can parse the “lifecycles” and make calls using the API can be used. I chose PHP. Unfortunately, the documentation is too heavily reliant on node.js examples to properly promote the claim that writing SmartApps are agnostic of language. It would read better if there were more examples in a variety of languages (Python, PHP, raw curl, etc.) In fact, why not have all the examples coded in the various languages as is often the case in REST API documentations.
One section in particular that stands out to me is signing. The document says, “A full discussion of HTTP signature verification is beyond the scope of this document”. I don’t think we need a section to explain Draft 3, but at least go over what the app has to actually do to verify (again, with curl code, or PHP, or others). Instead, it is all being hidden in the node.js SDK, and the document points you to the Draft. That’s rough. After a bit of digging I found that it was actually very straight forward to do it. Here is my PHP code just in case others come across this post:
$auth=explode(",",$_SERVER['HTTP_AUTHORIZATION']);
foreach($auth as $value) {
if(preg_match('/(\S*)="(.*)"/', $value, $matches)) {
$auth_info[$matches[1]] = $matches[2];
}
}
// get the public key
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "$keyUrl".$auth_info['keyId']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$auth_key = curl_exec($ch);
curl_close($ch);
$auth_data="";
$auth_data=$auth_data."(request-target): post ".$_SERVER['REQUEST_URI']."\n";
$auth_data=$auth_data."digest: ".$_SERVER['HTTP_DIGEST']."\n";
$auth_data=$auth_data."date: ".$_SERVER['HTTP_DATE'];
// verify
if(!openssl_verify($auth_data, base64_decode($auth_info['signature']), $auth_key, OPENSSL_ALGO_SHA256)) {
// respond
http_response_code(400);
header("content-type: application/json");
echo '{ "error" : "signature verification failed." }';
exit();
}
Of course, the code assumes that the headers section will always be
“(request-target) digest date”
and the algorithm is
“rsa-sha256”
I haven’t read anything anywhere in the documentation to say that this will consistently be so. Since that seems to be what was implemented in the SDK can we assume that it is safe to code signing in this way or do we really have to implement being able to respond to any permutation of headers and algorithms?
Thanks,
Jose