Other pages
This is a step by step guide to generate a signed URL to access endpoints via the cloud api. There are two types of signing:
JSON Web Tokens
Use JSON web tokens to generate a signature that can apply to a variety of urls and requests
Traditional
Generate a signature for a specific url including all query parameters using a simple hash
Contents
JSON web tokens are a standard way to sign arbitrary data using a secret that only the server knows. Since the data you are signing is flexible and included in the token itself, it provides more flexibility than traditional signing.
There are plenty of libraries available for generating and validating JWT, but at a high level it is pretty simple. A sample token looks like this
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJiaXRibGFzdDpHQnBpenYzeHQyIiwiaWF0IjoxNDM1NTA2MDcxLCJleHAiOjE0MzU1MDk2NzEsInBhdGgiOiIvaW5mbyoifQ.pzAWJLoPvkjh4lwk1ui2dyGBUcYHv2HlWjKeRn0xOnM
It is made up of three parts: a header, claims, and a signature. They are all base64 encoded and separated by a period.
<base64-urlencoded header>.<base64-urlencoded claims>.<base64-urlencoded signature>
When you decode it and break it down it looks like this
{ "typ": "JWT", "alg": "HS256" }
Parameter | Description | Required |
---|---|---|
typ | Specifies the type of token | Yes |
alt | Specifies the signing algorithm (HMAC SHA 256 in this case) | Yes |
The header should never change.
{ "iss": "bitblast:GBpizv3xt2", "iat": 1435506071, "exp": 1435509671, "path": "/info*" }
Parameter | Description | Required |
---|---|---|
iss | This is the token issuer. It is made up of the string bitblast concatenated with a : and your public Key from your settings. |
Yes |
iat | This is a UNIX timestamp of the time the token was generated | Yes |
exp | This is a UNIX timestamp of the time the token will expire | Yes |
path | This is the path or wildcard path that you want this token to be good for. In this example this token will be valid for any request that starts with /info . |
Yes |
The path can contain *
at the beginning or end or at both the begnning and end. For example *.json
would match any request that ends with .json, but if you had query string parameters they would not match. *.json*
would match any request that contains .json at any point within the url. /some/other/path
with no *
will match that path and that path only. /*
will match all requests.
You can also pass a regular expression for custom matches. For example
"path": "^/(info|probe)"
That will match any /info
or /probe
request, but that is it.
The signature is calculated by taking the base64 encoded values of the headers and claims, concatenating them with a period and using your secret that corresponds to the key you used in the iss
claim.
It is recommended to use a library to do this.
For more libraries check out the JSON Web Token page page.
Here is an example in python
import time import jwt headers = { 'typ': 'JWT', 'alg': 'HS256' } claims = { 'iss': 'bitblast:' + YOUR_KEY, 'iat': int(time.time()), 'exp': int(time.time()) + 3600, # Expires in one hour 'path': '/info*' } assertion = jwt.encode(claims, YOUR_SECRET_KEY, headers=headers) print(assertion.decode('utf-8'))
After you have generated the token you should include it as a query string parameter named token
. So your final URL might look something like this
/info?src=magnet%3A%3Fxt%3Durn%3Abtih%3ACNKKYRN7WPTEJICNNHGFDHUDFA55HLDK&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJiaXRibGFzdDpHQnBpenYzeHQyIiwiaWF0IjoxNDM1NTA2MDcxLCJleHAiOjE0MzU1MDk2NzEsInBhdGgiOiIvaW5mbyoifQ.pzAWJLoPvkjh4lwk1ui2dyGBUcYHv2HlWjKeRn0xOnM
First pick the endpoint that you want from the list of endpoints. For this example we will be using the info endpoint.
The base url is
https://cloud.bitblast.io/info
We only care about the ending though /info
. The magnet URL for the torrent we want to get info about is
magnet:?xt=urn:btih:CNKKYRN7WPTEJICNNHGFDHUDFA55HLDK
This means the uri we want to request is
var magnetUrl = 'magnet:?xt=urn:btih:CNKKYRN7WPTEJICNNHGFDHUDFA55HLDK'; var baseUri = '/info'; var fullUri = baseUri + '?src=' + encodeURIComponent(magnetUrl);
Which turns out to be
/info?src=magnet%3A%3Fxt%3Durn%3Abtih%3ACNKKYRN7WPTEJICNNHGFDHUDFA55HLDK
The signing mechanism is similar to Amazon S3 so if you are familiar with that then great. First you are going to need to copy your secret key out of your settings.
You need to first generate a UNIX timestamp for when you want your signature to expire.
var expires = Math.round(new Date().getTime() / 1000) + 3600;
Now create an hmac_sha1 hash using your secret key from your settings and add the fullUri
and expires
to the hash. The signature is the resulting digest base64 encoded.
var hmac = crypto.createHmac('sha1', YOUR_SECRET_KEY); var digest = hmac.update(fullUri + expires).digest(); var signature = new Buffer(digest).toString('base64');
After you have the uri and the signature you just need to add a few extra parameters to the end of the url.
&key={YOUR_API_KEY}&exp={EXPIRES_TIMESTAMP}&sig={SIGNATURE}
So now the final URL will look a little something like this
/info?src=magnet%3A%3Fxt%3Durn%3Abtih%3ACNKKYRN7WPTEJICNNHGFDHUDFA55HLDK&key=GBpizv3xt2&exp=1435442273&sig=DqAAHWl4W9hXG5GkeK2/00d2QSw=
It doesn't matter which order you append these parameters, but they have to be the last 3 query parameters included with the URL.