While there are many examples out there on the web of how to implement an OAuth flow, we thought it might be useful to have it explicitly described, with examples, to help you better understand the process, and also to give you a deeper look at the structure and functionality of the SnowShoe API and SDKs.
Note: This discussion applies only to web apps.
So lets start at the beginning.
A good starting point is to discuss the “data” element, because that is where everything begins. When a snowshoe stamp is touched to the screen of a device, we use a javascript canvas to observe a set of five coordinate pairs. These coordinate pairs comprise the “data” element. Snowshoe provides 2 separate options for obtaining this data: Our hosted stamp screen, which can be found at:
http://beta.snowshoestamp.com/applications/client/[app_key]/
Or, by using the Touchy SDK, which allows you to host your own stamp screen. Lets take a quick look at the Touchy SDK, because it will allow us to move on to the next step rather easily:
<script type=”text/javascript” src=”api/js/vendor/touchy.js”></script>
<script type=”text/javascript” src=”api/js/sss.client.js”></script>
<script type=”text/javascript” src=”api/js/sss.util.js”></script>
<script type=”text/javascript” src=”core/js/jquery/jquery.json-2.4.min.js”></script>
<script>
body = document.getElementsByTagName(“body”)[0];
Touchy(body, {
five: function (hand, finger1, finger2, finger3, finger4, finger5) {
hand.on(‘start’, function (points) {
data=[];
for(x in points){
data[x] = [points[x][“x”], points[x][“y”]];
}
sss.client.init(“/demo/hidden/”);
sss.client.call(data);
});
}
});
</script>
data=[];
for(x in points){
data[x] = [points[x][“x”], points[x][“y”]];
}
sss.client.init(“/demo/hidden/”);
sss.client.call(data);
Here we collect the coordinates pairs(the “points” array contains the coordinates from the touch events) and put them in the format required by the SnowShoe API. The appropriate format of points for submitting a request to the Snowshoe API starts out like this:
[[x1,y1],[x2,y2],[x3,y3],[x4,y4],[x5,y5]]
Here is a sample data set with correct formating:
[[190,356],[607,363],[202,1107],[756,563],[752,1116]]
When sss.client.call recieves this data, what does it do?
base64 encoding
The first thing it does is base64 encode them, using the util package that comes along with the Touchy SDK:
sss.util.base64.encode($.toJSON(data))
The javascript that we use to do that encoding is a standard function widely available online. If you want to see it, you can view the code here, or in our SDK : http://www.webtoolkit.info/javascript-base64.html
If you encode the sample data set we provided above, you will get the following output:
W1sxOTAsMzU2XSxbNjA3LDM2M10sWzIwMiwxMTA3XSxbNzU2LDU2M10sWzc1MiwxMTE2XV0=
POST to your app callback
Now, its time to move server side. If you are using the Touchy SDK, the sss.client.call function sends the encoded “data” element as a POST variable to the callback you registered in index.html. If you are using our hosted stamp screen, the same thing happens, only it’s using the callback you registered in your app on our developer portal.
We have several server-side SDKs available, and each one helps you setup the callback that is needed for the above process to move forward. The callback MUST be written in a server-side language, because it makes use of your private app secret which you do NOT want to expose to the world. Server-side languages like PHP and Python are executed on your server where no one has access to them, so it allows your OAuth request to be truly secure.
Lets look at the PHP SDK as an example. Below is the contents of callback.php
include (“./inc/SSSApiClient.php”);
$app_key=”abcdefg”; // put app key here
$app_secret=”abcdefg”; // put app secret here
$data=$_POST[‘data’];
$client= new SSSApiClient($app_key, $app_secret);
$JSONResponse=$client->processData($data);
//parse $JSONResponse to determine if a stamp was found.
//We just echo it here.
echo $JSONResponse;
You can see that $data is pulling in the data element that was POSTed from the stamp screen.
SSSApiClient
The next two lines call “SSSApiClient” to construct a signed request and POST that request to a signed URL:
$client= new SSSApiClient($app_key, $app_secret);
$JSONResponse=$client->processData($data);
Lets look at the contents of SSSApiClient:
class SSSApiClient {
protected $app_key = null;
protected $app_secret = null;
public function __construct($app_key, $app_secret) {
$this->app_key = $app_key;
$this->app_secret = $app_secret;
}
public function processData($data) {
$data = array(“data” => $data);
$app_key = $this->app_key;
$app_secret = $this->app_secret;
$oauth = new OAuthSimple();
$result = $oauth->sign(
Array(“path” => “http://beta.snowshoestamp.com/api/v2/stamp",
“parameters” => $data,
“action” => “POST”,
“signatures” => Array(“consumer_key” => $app_key,
“shared_secret” => $app_secret)));
$header = $oauth->getHeaderString();
$ch = curl_init($result[‘signed_url’]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch,CURLOPT_HTTPHEADER,array(“Authorization:".$header));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, ‘POST’);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
$return = curl_exec($ch);
$curlError = curl_error($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
return $return;
}
}
It looks like there is a lot going on in here, but really, its pretty straightforward.
The “$oauth->sign” line takes the parameters given, and generates a signature based on the signature base string (a specially formatted string containing, in specific order, the API URL, the request method “POST”, and all the query parameters,) using HMAC-SHA1 and your app secret. I won’t go too deeply into this, the important thing to know is that there are OAuth libraries that can take care of this for you in practically every language.
Authorization Header
Once thats done, the next line, $oauth->getHeaderString() returns the following:
OAuth oauth_nonce=”4aJJA”, oauth_timestamp=”1402497082", oauth_consumer_key=”393ae81751dfbb1377cf”, oauth_signature_method=”HMAC-SHA1", oauth_version=”1.0", oauth_signature=”YCPRg%2FOp57Fm7RdOB0PwA1zqZMg%3D”
That is the format of an Authorization header, and so when you generate the request, you must include an Authorization header similar to the above string.
Making your request
Once you have your Authorization header, the next step is to actually make the request. You want to make this request to a signed URL, which contains the parameters you’ve generated. In the above case, the signed URL would look something like this:
http://beta.snowshoestamp.com/api/v2/stamp?data=W1sxOTAsMzU2XSxbNjA3LDM2M10sWzIwMiwxMTA3XSxbNzU2LDU2M10sWzc1MiwxMTE2XV0%3D&oauth_consumer_key=393ae81751dfbb1377cf&oauth_nonce=4aJJA&oauth_signature=YCPRg%2FOp57Fm7RdOB0PwA1zqZMg%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1402497082&oauth_version=1.0
Note that everything has been properly URL encoded here.
So the full request looks like this:
curl -X POST ‘http://beta.snowshoestamp.com/api/v2/stamp?data=W1sxOTAsMzU2XSxbNjA3LDM2M10sWzIwMiwxMTA3XSxbNzU2LDU2M10sWzc1MiwxMTE2XV0%3D&oauth_consumer_key=393ae81751dfbb1377cf&oauth_nonce=4aJJA&oauth_signature=YCPRg%2FOp57Fm7RdOB0PwA1zqZMg%3D&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1402497082&oauth_version=1.0'
-H ‘Authorization: OAuth oauth_nonce=”4aJJA”, oauth_timestamp=”1402497082", oauth_consumer_key=”393ae81751dfbb1377cf”, oauth_signature_method=”HMAC-SHA1", oauth_version=”1.0", oauth_signature=”YCPRg%2FOp57Fm7RdOB0PwA1zqZMg%3D”’
This request will return a JSON that contains the serial number of any stamp found. What you do with that serial number is entirely up to you, but here are a couple tutorials to get you started:
Email me when SnowShoe publishes or recommends stories