Introduction
In this guide, we will learn how to authenticate and authorize a Camera to Cloud (C2C) hardware device on a Frame.io project. We will cover both the traditional pairing method using manual code entry and the new QR code pairing method for an enhanced user experience.
What Will I Need?
If you haven’t read the Before We Start Implementing guide, give it a quick glance before moving on!
Additionally, you should have received a client_secret
from our team that will be used to identify your integration. If you have not received a client_secret
, please take a look at this introduction to the C2C ecosystem and reach out to our team.
Prerequisites for QR Code Pairing
Before starting with QR code pairing, ensure the following prerequisites are met:
- Feature Flag Activation: A specific feature flag (
v4.c2c_qr_code_activate
) must be enabled in your Frame.io account. This feature flag will allow access to the QR code-based pairing method. Your designated Frame.io point of contact can assist in turning on this feature for the account of your choice. - Camera Compatibility: Ensure your camera hardware is updated to support QR code generation during the device pairing process.
Walking Through the Hardware Auth Flow
Let’s make sure we have a high-level understanding of the expected user experience for the authorization flow we want to implement. Check out the following resources to see this flow from the user’s point of view:
- Support Article for how to add new hardware devices.
- Training video on how to authorize a Teradek Cube.
The hardware authorization flow is designed to lift as many details as possible off the implementer, and therefore the device UI. With this flow, you do not need to worry about:
- Redirecting to a web browser.
- Handling Frame.io user login/authentication.
- Listing/selecting the account and project to connect to.
- Any UI elements beyond basic information displays.
Enhancing the User Experience with QR Code Pairing
As the demand for efficiency and ease of use grows, users are increasingly expecting seamless interactions with their devices. The current process for pairing cameras to Frame.io's C2C service requires several steps, including the manual input of a pairing code. While functional, this process can be streamlined.
By leveraging QR codes—similar to the device pairing experiences seen with streaming services like Netflix or Disney+—we can simplify the process, eliminate errors caused by manual input, and reduce the time it takes to pair a camera.
Device Identification (client_id
)
When connecting to Camera to Cloud, each physical hardware device will need to identify itself uniquely so we can list device connections in a user’s project.
For hardware devices, we call this the client_id
of the device, depending on what authorization pattern you choose to use. When setting up your implementation, you should think about how you will do this. You could use a serial number of the hardware device, a UUID, or some uniquely identifying string.
Be careful not to leak personally identifying information. The user’s email, for instance, is not a valid value to use as a client_id
.
Likewise, make sure you own the unique identifier. If you are implementing the C2C API as a software device, do not use the device’s MAC address, for instance. The MAC address is not owned by your software and might also be considered personally identifying information.
If you’re not sure what value you would like to use, we can talk through this choice together and make sure a suitable value is chosen that makes integration as easy as possible.
Step 1: Requesting a Device Code
Let's start implementing. The first thing we need to do is request a device code to give the user for a device. We do that by calling the /v2/auth/device/code
endpoint:
Traditional Pairing Method
curl -X POST https://api.frame.io/v2/auth/device/code \
--form 'client_id=[client_id]' \
--form 'client_secret=[client_secret]' \
--form 'scope=asset_create offline' \
| python -m json.tool
Enabling QR Code Pairing
To enable QR code-based pairing, a minor change in the API call is required. Specifically, two new headers need to be added to the device code request. This allows devices to link directly to the pairing page and streamline the pairing process.
curl -X POST https://api.frame.io/v2/auth/device/code \
--header "x-client-version: 2.0.0" \
--header "x-client-platypus-enabled: true" \ # New header to enable QR code
--form 'client_id=[client_id]' \
--form 'client_secret=[client_secret]' \
--form 'scope=asset_create offline' \
| python -m json.tool
Note: We are using form data here rather than JSON data. The C2C authentication endpoints only accept form data. Once you are authenticated, other endpoints will accept JSON payloads, but the authentication endpoints will return an error if JSON payloads are sent.
Payload Parameters
- client_id: A unique identifier for the physical hardware device. This value needs to be guaranteed to be unique for the device. This could be a serial number or a randomly generated UUID.
- client_secret: This will be issued to you by Frame.io support and identifies your device model. This value should be kept secret from the user and should be encrypted at rest.
- scope: The permissions we are requesting, with spaces used as delimiters. Hardware devices can only request the following two scopes:
asset_create
: Allows the device to create and upload assets.offline
: Allows the device to refresh its own authorization using a refresh token. Authorization tokens expire after 8 hours, so without this scope, a user would need to re-authorize their device every 8 hours.
In practice, devices will almost always want to request both scopes.
Understanding the API Response
When we make the request, we will get a response similar to the following:
Traditional Pairing Response
{
"device_code": "[device_code]",
"expires_in": 120,
"interval": 5,
"name": "MyDevice-[client_id]",
"user_code": "573131"
}
QR Code Pairing Response
{
"device_code": "[device_code]",
"expires_in": 120,
"interval": 5,
"name": "MyDevice-[client_id]",
"user_code": "573131",
"verification_uri": "https://next.frame.io/pair",
"verification_uri_complete": "https://next.frame.io/pair/573131"
}
Response Breakdown
- device_code: The device code should be hidden from the user and is used to identify this authorization request when polling to see if the user has entered the code successfully.
- expires_in: The number of seconds until this code expires.
- interval: How long the user should wait between polling requests to see if the user has entered the code.
- name: The name of the device we are trying to connect.
- user_code: The six-digit code the user will enter into Frame.io to pair the device to a project.
- verification_uri: This is the URL users will manually enter in the event the QR code is not scanned. It should be concise and easy to remember.
- verificationuricomplete: This URL contains the pairing code and is intended for non-textual transmission (e.g., the QR code). When scanned, it will automatically route the user to the pairing experience, to pick an account and project to connect their device to.
Putting the Steps Together
Now that we know the calls we need to make, let's put them together into some Python-like pseudocode. Remember, it's possible for our device code to expire, so we need to handle that possibility when setting up our logic:
def authorize_with_frame():
"""
Handles authorizing our device with Frame.io.
"""
# Our client ID can be a serial number, UUID, or some other unique string.
client_id = THIS_DEVICE.get_serial_number()
while True:
# Make the call to Frame.io to get our device codes.
pairing_codes = c2c.get_device_codes(client_id)
# We need to keep track of how long we have been polling for
polling_started = datetime.now()
# Now we are going to poll for authorization until the user enters the code.
while True:
# Re-write this output each time we poll. Note: This message will only update once
# per `interval` (e.g., 5 seconds), so if a smooth countdown is desired, that will
# need a different implementation.
print(
f"\rPAIRING CODE: {pairing_codes.user_code}, "
f"EXPIRES IN: {pairing_codes.expires_in - (datetime.now() - polling_started).seconds} seconds"
)
# Wait for `interval` before polling each time.
sleep(pairing_codes.interval)
# Make a call to Frame.io to see if the user has entered the code and authorized
# the device.
authorization, error = c2c.poll_for_authorization(
client_id, pairing_codes.device_code
)
if error and error.message == "authorization_pending":
# If the authorization is pending, try again.
continue
elif error and error.message == "expired_token":
# If the pairing codes have expired, break to generate new codes.
break
elif error:
# If we get another error, we should raise it. (advanced error handling will
# be covered in another tutorial)
raise Exception(error.message)
return authorization
Note: In this pseudocode, we've added an outer loop to handle the case where the pairing codes expire, and we need to request new ones.
The last thing we should do is fetch the information about the project we have connected to from Frame.io and display it to the user for an extra layer of confirmation that the device was paired to the intended project. We'll show that in the next tutorial.
Troubleshooting
If you find yourself here, then something has gone wrong! What would integrating with a third party be without some sort of error? This section lists a set of common issues and will walk you through the steps most likely to solve them. Take a look through the following list and see if anything matches the issue you're experiencing.
If you don’t find a solution here, we would love to hear the issue you ran into so we can add it here.
- I Don’t See a "Connect Device" Button: If you go to the C2C management panel and don't see a "Connect Device" button, then one of two things is happening:
C2C is Not Enabled for Your Account: If the screen is blank and there is a message about C2C not being available for your account, the account manager needs to enable it for your project in the account settings.- You Are Not a Device Manager: If the screen is blank and there is a message about not having permissions, then the account manager either needs to change the permissions for who is allowed to connect C2C devices, or add you into a role that has those permissions.
- You Already Have a Device Connected: After the first device is connected, the big blue "Add New Device" button goes away, and instead you need to go to the three-dot menu in the upper-right-hand corner of the C2C Connections panel.
- Invalid Client Error:
invalid_client
is returned when the information you are providing to us about the device does not match anything we have on record. This most likely means that yourclient_secret
is incorrect. - Bad Request Error:
bad_request
is returned when the request data is malformed in some way. Double-check that you have not misspelled a field name or forgotten to add a required field.
Parking lot
To do
Add contingency to partners who cannot generate a dynamic QR Code
aka have them display “Go to **verification_uri**
to enter this code" as a backup plan