Example: Creating additional Tokens for Devices


This is a demonstration of how to create restricted Tokens for your devices, giving you security without compromising on flexibility.

To understand more about what Tokens are, we suggest starting with the Token Object Overview.

A Brief Recap


To create your flowthings.io application, you will have used your Master Token to authenticate your requests. The Master Token allows full, unrestricted access to your account. For this reason, it is recommended that the Master Token is used only for creating and editing applications, and not for devices.

Fortunately, you can generate an unlimited number of Token objects which are restricted to reading and / or writing drops, within a namespace of your choosing

Creating a new Token


Let's begin by creating a Token for a device. In this case, we want a Token for a Thermostat, which is part of a Home Automation system.

The current application looks like this:

FLOW: /alice/home-automation/
FLOW: /alice/home-automation/doorlock1
FLOW: /alice/home-automation/doorlock2
FLOW: /alice/home-automation/thermostat
FLOW: /alice/home-automation/thermostat/history
FLOW: /alice/home-automation/user-commands

We must use the Master Token to generate all our Token Objects for our devices.

curl https://api.flowthings.io/v0.1/alice/token/ \
    -H "X-Auth-Token: IlmK7uLSzQvXruJbyGMCfrcU05p52NXp" \
    -H "Content-Type: application/json" \
    -d '{
            "paths" : {
                "/alice/home-automation/thermostat" :
                    { "dropRead" : true, "dropWrite" : true },
                "/alice/home-automation/user-commands" :
                    { "dropRead" : true, "dropWrite" : false }
            }
        }'

## Response:

{
    "head": {
        "status":201,
        "ok":true,
        "messages":["Your request has been processed successfully. A new resource has been created."],
        "errors":[],
        "references":{}
    },
    "body": {
        "id":"k54a30f12d4c65af20a9cb52c",
        <...snip...>
        "tokenString":"NnoDfY7u4q5Y532QF0yOlKgtSr36"
    }
}

A Token has been generated. Note the tokenString attribute: this is the string which will be passed to the X-Auth-Token header for all requests sent by our Thermostat.

The Token spec contains a map of paths and the access writes for each. By default, every Token object is given Read access for objects (Flows, Tracks etc.) under each path listed. In addition, we've specified that the Thermostat can read and write drops to /alice/home-automation/thermostat. We've also given the device drop-read-only access to /alice/home-automation/user-commands.

Taking it for a spin

Let's test out what the Token can and can't do!

Firstly, we can read any object within the namespaces specified. Note the use of the new token string for x-auth-token!

curl https://api.flowthings.io/v0.1/alice/flow \
      -G -H "X-Auth-Token: NnoDfY7u4q5Y532QF0yOlKgtSr36"

## Response:
{
    "head": {
        "status":200,
        "ok":true,
        "messages":[],
        "errors":[],
        "references":{}
    },
    "body":[
        {
            "id":"f54a30e64d4c65af20a9cb51d",
            <...snip...>,
            "path":"/alice/home-automation/thermostat"
        },
        {
            "id":"f54a30e69d4c65af20a9cb522",
            <...snip...>,
            "path":"/alice/home-automation/thermostat/history"
        },
        {
            "id":"f54a30edad4c65af20a9cb527",
            <...snip...>,
            "path":"/alice/home-automation/user-commands"
        }
    ]
}%

We queried for all Flows within our namespace, but only 3 were returned - those to which we have access. Notice how we are also able to view /alice/home-automation/thermostat/history - Token paths are recursive.

If we attempt to create any new objects other than Drops, we will be denied:

curl https://api.flowthings.io/v0.1/alice/flow \
    -H "X-Auth-Token: NnoDfY7u4q5Y532QF0yOlKgtSr36"  \
    -d '{ "path" : "/alice/home-automation/dangerous" }'

## Response:
{
    "head": {
        "status":403,
        "ok":false,
        "messages":[],
        "errors":["Access to the requested resource is forbidden.Cannot CREATE Flow with actor(54932047d4c67eee1cbdbd31)"],
        "references":{}
    },
    "body":{}
}

We've granted the Token the ability to write drops under /alice/home-automation/thermostat, so let's do just that:

curl https://api.flowthings.io/v0.1/alice/drop/ \
    -H "X-Auth-Token: NnoDfY7u4q5Y532QF0yOlKgtSr36" \
    -H "Content-Type: application/json" \
    -d '{
            "path" : "/alice/home-automation/thermostat",
            "elems": {
                "mode" : "timer",
                "temperature" : {
                    "value" : 60,
                    "metric": "F"
                }
            }
        }'

(returns OK)

Once again, we cannot read or write Drops to locations which we haven't granted access.

Revoking the Token

If for whatever reason, you wish to revoke access from a device, the Token can be deleted. No further requests can be made using the Token.

We must use the Master Token to do any revoke operations:

curl https://api.flowthings.io/v0.1/alice/token/k54a30f12d4c65af20a9cb52c \
    -H "X-Auth-Token: IlmK7uLSzQvXruJbyGMCfrcU05p52NXp" \
    -H "Content-Type: application/json" \
    -X DELETE