Introduction
In this guide, we will learn how to refresh, revoke, and store hardware device authorization information for Frame.io.
What will I need?
If you haven’t read the Implementing C2C: Setting Up guide, give it a quick glance before moving on!
You’ll need the client_secret
given to you by our team, and the same client_id
you used in the authentication and authorization guide. The access_token
and refresh_token
is also required to complete this guide.
Refreshing your access token
If you make a call to our API that requires an access token and get the following response:
{
"code": 401,
"errors": [
{
"code": 401,
"detail": "You are not allowed to access that resource",
"status": 401,
"title": "Not Authorized"
}
],
"message": "Not Authorized"
}
... then your access token has expired!
To refresh your token, we’ll make the following call:
curl -X POST https://api.frame.io/v2/auth/token \
--header 'x-client-version: 2.0.0' \
--form 'client_id=[client_id]' \
--form 'client_secret=[client_secret]' \
--form 'grant_type=refresh_token' \
--form 'refresh_token=[refresh_token]' \
| python -m json.tool
Docs for /v2/auth/token
can be found here
All these values were generated in the previous guide. Take a look if you haven’t already, then come back here!
By using all these values (instead of just the refresh token), we make it impossible to generate new authorization from a leaked refresh token online. If someone wants to generate a token as if they were your integration, they will need both the refresh_token
and the client_secret
.
You should get a response like this:
{
"access_token": "[access_token]",
"expires_in": 28800,
"refresh_token": "[refresh_token]",
"token_type": "bearer"
}
These are your new authorization tokens. Once you have refreshed your tokens, the old tokens will no longer work, so make sure you keep these handy!
If we try using our old refresh token to refresh now, we will get an error:
{
"error": "invalid_request"
}
Our token has already been refreshed, so using the existing refresh token is invalid.
If you get a 401 Not Authorized
response while refreshing your tokens, then your token is no longer valid and you will need to restart the authorzation process over again.
Missing a refresh response
refresh_token
values can be used once and only once. If you make a call to Frame.io to refresh a token, and miss the response, either due to a network error or unexpected power cycle, then you will need to restart the entire authentication / authorization flow.
This is an unfortunate possibility, but it’s better to be safe than sorry!
Revoking your tokens
In some instances, we might want to “sign out” of Frame.io. A user might decide they no longer want to be connected after completing a shoot, for instance. Revoking authorization is also a good practice if your app gets into a bad state and needs to reset to a clean slate. Any time you know you are planning to discard its current authorization, your app should make an attempt to revoke it.
To revoke our authorization, we make the following call:
After you make this call you will need to restart the authentication & authorization process detailed in the last guide.
curl -X POST https://api.frame.io/v2/auth/revoke \
--include \
--header 'x-client-version: 2.0.0' \
--form 'client_id=[client_id]' \
--form 'client_secret=[client_secret]' \
--form 'token=[refresh_token]
Docs for /v2/auth/revoke
can be found here
The response will not contain a payload. We used --include
in the command to print the returned headers, which should start with a status code of 200
if out call succeeded:
HTTP/2 200
...
Now that our token has been revoked, all calls to Frame.io that require an access_token
will return with Not Authorized
, and if the user wishes to use the Frame.io connection again, they will need to re-pair their device to the project.
Storing tokens
In order to maintain functionality across power cycles, you will need to store your authorization headers at rest. This can be done in a file, a database, or in your own cloud. Here are a few guidelines for storing authorization tokens:
Do not allow the user to see or access the tokens. Your user should never be allowed to view or retrieve their tokens. They should be managed by your app and your app alone.
Encrypt your tokens at rest. Just as with the client_secret
, access and refresh tokens should be encrypted at rest when possible to prevent keys from being stolen. Authorization keys should not be stored in plaintext.
Do not store your authorization tokens in the same file as your client_secret. The example Python app stores the client_secret
and client_id
in the same file as its authorization tokens. This works fine for a demo, but is not a good practice for production code. client_secret
and client_id
are static values for a device, and the device will stop functioning if they are lost.
The authorization tokens are not static, and will need to be re-written many times over the lifetime of the device. If the device were to lose power while updating a file with new tokens, that file could become corrupted, and the client_secret
could be lost, resulting in the device being unable to re-authenticate at Frame.io ever again. By separating the tokens, at worst, a user will have to pair the device again.
The best place to store tokens would be a proven database like SQLite, but at the very least authorization data should be separated from our other values.