操作指南:授权(硬件)

前言

在本指南中,我们将学习如何在 Frame.io 项目中对 Camera to Cloud (C2C) 硬件设备进行身份验证和授权。我们将介绍传统的配对方法(使用手动代码输入)以及新的 QR 代码配对方法(旨在提升用户体验)。

我需要准备什么?

如果您还未阅读开始实施之前的准备指南,请先快速浏览一下再继续操作!此外,您应该已收到我们团队提供的 client_secret,它将用于标识您的集成。如果您尚未收到 client_secret,请查阅这份 C2C 生态系统简介,并联系我们的团队。

QR 代码配对的前提条件

开始 QR 代码配对之前,请确保满足以下前提条件:

  • 功能标记激活:您的 Frame.io 帐户中必须启用一个特定的功能标记 (v4.c2c_qr_code_activate)。此功能标记将允许访问基于 QR 代码的配对方法。您指定的 Frame.io 联系人可以协助为您选择的帐户启用此功能。
  • 相机兼容性:确保您的相机硬件已更新,以支持在设备配对过程中生成 QR 代码。

了解硬件授权流程

我们首先需要从较高层次上理解所要实施的授权流程中,预期的用户体验是怎样的。请查阅以下资源,从用户角度了解此流程:

  • 关于如何添加新硬件设备的支持文章。
  • 关于如何授权 Teradek Cube 的培训视频。

硬件授权流程旨在尽可能减轻实施者以及设备 UI 的负担。通过该流程,您无需担心以下问题:

  • 重定向到 Web 浏览器。
  • 处理 Frame.io 用户登录/身份验证。
  • 列出/选择要连接的帐户和项目。
  • 除基本信息显示之外的任何 UI 元素。

通过 QR 代码配对提升用户体验

随着对效率和易用性需求的增长,用户越来越期望与设备之间实现无缝交互。当前将相机与 Frame.io 的 C2C 服务配对的流程需要多个步骤,其中包括手动输入配对代码。虽然该流程能正常工作,但仍有简化空间。

通过利用 QR 代码(类似于 Netflix 或 Disney+ 等流媒体服务中的设备配对体验),我们可以简化流程、消除手动输入导致的错误,并缩短相机配对所需的时间。

设备标识 (client_id)

在连接到 Camera to Cloud 时,每台物理硬件设备都需要唯一标识自身,以便我们可以在用户项目中列出设备连接。

对于硬件设备,我们将此称为设备的 client_id,具体取决于您选择使用的授权模式。在设置实施时,您应该考虑如何生成这个标识符。您可以使用硬件设备的序列号、UUID 或某种唯一标识字符串。请注意:不要泄露个人身份信息。例如,用户的电子邮件地址就不能作为 client_id 的有效值。

同样,请确保您拥有唯一标识符。例如,若您是将 C2C API 作为软件设备来实施,请勿使用设备的 MAC 地址。MAC 地址并非由您的软件所有,也可能被视为个人身份信息。

如果您不确定要使用什么值,我们可以一起讨论这个选择,确保选出一个合适的值,以便尽可能简化集成过程。

步骤 1:请求设备代码

让我们开始实施。我们需要做的第一件事是请求一个设备代码,以便提供给用户用于设备配对。我们通过调用 /v2/auth/device/code 端点来完成此操作:

传统配对方法

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

启用 QR 代码配对

要启用基于 QR 代码的配对,需要在 API 调用中进行一个小改动。具体而言,需要向设备代码请求添加两个新的标头。这样设备可以直接链接到配对页面,从而简化配对流程。

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

**注意:**我们在这里使用的是表单数据而非 JSON 数据。C2C 身份验证端点仅接受表单数据。一旦您通过身份验证,其他端点将接受 JSON 负载,但如果向身份验证端点发送 JSON 负载,则会返回错误。

负载参数

  • client_id:物理硬件设备的唯一标识符。该值需要保证对设备唯一。可以是序列号或随机生成的 UUID。
  • client_secret:此值将由 Frame.io 支持团队颁发给您,用于标识您的设备型号。该值应对用户保密,并应在静态存储时进行加密。
  • scope:我们请求的权限,使用空格作为分隔符。硬件设备只能请求以下两个权限范围:
  • asset_create:允许设备创建和上传资产。
  • offline:允许设备使用刷新令牌来刷新自身的授权。授权令牌在 8 小时后过期,因此如果没有此权限范围,用户需要每 8 小时就重新授权一次他们的设备。

在实际应用中,设备几乎总是希望同时请求这两个权限范围。

理解 API 响应

当我们发出请求时,会得到类似如下的响应:

传统配对响应

{
"device_code": "[device_code]",
"expires_in": 120,
"interval": 5,
"name": "MyDevice-[client_id]",
"user_code": "573131"
}

QR 代码配对响应

{
"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"
}

响应细分

  • device_code:设备代码应对用户隐藏,用于在轮询查看用户是否已成功输入代码时,标识此次授权请求。
  • expires_in:该代码的有效期,单位为秒。
  • interval:检查用户是否已输入代码时,每次轮询之间应等待的时间。
  • name:我们尝试连接的设备的名称。
  • user_code:用户在 Frame.io 中输入以将设备配对到项目的六位数代码。
  • verification_uri:这是在未扫描 QR 代码的情况下,用户将手动输入的 URL。它应该简洁且易于记忆。
  • verification_uri_complete:此 URL 包含配对代码,用于非文本传输(例如 QR 代码)。扫描后,它会自动将用户引导至配对界面,以选择要连接其设备的帐户和项目。

向用户显示 QR 代码

现在我们有了 verification_uri_complete,就可以根据此 URL 生成 QR 代码,并在设备屏幕上显示给用户。这样用户只需用他们的移动设备或相机扫描 QR 代码即可,从而简化配对流程。

示例:显示 QR 代码的相机屏幕

插入显示 QR 代码的相机屏幕图像或示意图。

如果用户因任何原因无法扫描 QR 代码,您还必须显示 user_codeverification_uri,以便他们可以手动输入配对代码作为备用方案。或者,您也可以将 verification_uri 显示为静态 QR 代码,供用户用移动设备扫描。如果您的集成是移动设备上的应用程序,则必须将 verification_uri_complete 显示为超链接供用户点击,以实现轻松连接,因为用户无法用正在运行该应用程序的同一台设备扫描 QR 代码。

步骤 2:轮询用户授权

一旦我们向用户提供了配对代码或显示了 QR 代码,就需要检查用户是否已输入该代码。为此,我们可以发出以下请求:

curl -X POST https://api.frame.io/v2/auth/token \
--form 'client_id=[client_id]' \
--form 'device_code=[device_code]' \
--form 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
| python -m json.tool

负载参数

  • client_id:与步骤 1 中发送的 client_id 相同。
  • device_code:由 /v2/auth/device/code 返回的 device_code
  • grant_type:我们的 OAuth 系统颁发的授权凭证类型。此值将始终为 urn:ietf:params:oauth:grant-type:device_code

前几次发出此请求时,我们可能会收到类似如下的响应:

{
"error": "authorization_pending"
}

但不用担心!这并非致命错误。它只是意味着用户尚未在 Frame.io 的 UI 中输入用户代码。我们只需继续轮询,直到用户完成输入即可。

反之,如果我们收到类似如下错误:

{
"error": "expired_token"
}

这意味着我们的代码在用户输入之前就已经过期了。在这种情况下,我们应该使用步骤 1 生成一个新的配对代码或 QR 代码,将其显示给用户,然后继续轮询。

最终,我们应该会收到类似如下的响应:

{
"access_token": "[access_token]",
"expires_in": 28800,
"refresh_token": "[refresh_token]",
"token_type": "bearer"
}

如果您的响应负载看起来像上面那样:恭喜!您已经授权了第一个 Camera to Cloud 设备。花点时间庆祝一下吧!

庆祝之后,让我们仔细查看该响应负载,确保我们理解它:

  • access_token:这是您访问 Frame.io 其余后端服务的密钥。在本教程系列后续将要发起的请求中,我们需要将其添加到请求的标头中。
  • expires_inaccess_token 的有效期,单位为秒。令牌有效期结束后,需要对其进行刷新,我们将在后续教程中详细介绍。
  • refresh_token:我们可用来管理 access_token 的令牌。最常用于刷新授权,但也可用于撤销授权。
  • token_type:对于 C2C API,将始终为 bearer,且不可操作。

将各个步骤整合起来

现在我们知道了需要发起的调用,让我们将它们整合成一些类似 Python 的伪代码。请记住,我们的设备代码可能会过期,因此在设置逻辑时需要处理这种可能性:

Python
1def authorize_with_frame():
2 """
3 Handles authorizing our device with Frame.io.
4 """
5
6 # Our client ID can be a serial number, UUID, or some other unique string.
7 client_id = THIS_DEVICE.get_serial_number()
8
9 while True:
10 # Make the call to Frame.io to get our device codes.
11 pairing_codes = c2c.get_device_codes(client_id)
12
13 # We need to keep track of how long we have been polling for
14 polling_started = datetime.now()
15
16 # Now we are going to poll for authorization until the user enters the code.
17 while True:
18
19 # Re-write this output each time we poll. Note: This message will only update once
20 # per `interval` (e.g., 5 seconds), so if a smooth countdown is desired, that will
21 # need a different implementation.
22 print(
23 f"\rPAIRING CODE: {pairing_codes.user_code}, "
24 f"EXPIRES IN: {pairing_codes.expires_in - (datetime.now() - polling_started).seconds} seconds"
25 )
26
27 # Wait for `interval` before polling each time.
28 sleep(pairing_codes.interval)
29
30 # Make a call to Frame.io to see if the user has entered the code and authorized
31 # the device.
32 authorization, error = c2c.poll_for_authorization(
33 client_id, pairing_codes.device_code
34 )
35
36 if error and error.message == "authorization_pending":
37 # If the authorization is pending, try again.
38 continue
39 elif error and error.message == "expired_token":
40 # If the pairing codes have expired, break to generate new codes.
41 break
42 elif error:
43 # If we get another error, we should raise it. (advanced error handling will
44 # be covered in another tutorial)
45 raise Exception(error.message)
46
47 return authorization

**注意:**在此伪代码中,我们添加了一个外层循环来处理配对代码过期后需要重新请求新代码的情况。我们最后应该做的一件事是:从 Frame.io 获取有关我们已连接项目的信息,并将其显示给用户,以便额外确认设备已配对到预期项目。我们将在下一个教程中展示这一点。

故障排除

如果您发现自己来到了这里,那说明出了问题!与第三方集成,哪能不出点差错呢?本节列出了一些常见问题,并将引导您完成最有可能解决这些问题的步骤。请浏览以下列表,看看是否有与您当前遇到的问题相符的情况。

如果您在此处没有找到解决方案,我们很乐意听取您遇到的问题,以便我们可以将其添加到这里。

  • 我看不到“连接设备”按钮:如果您前往 C2C 管理面板,但没有看到“连接设备”按钮,那么可能是以下两种情况之一:
  • 您的帐户未启用 C2C:如果屏幕空白,并且有一条消息提示您的帐户无法使用 C2C,那么客户经理需要在帐户设置中为您的项目启用 C2C。
  • 您不是设备管理员:如果屏幕空白,并且有一条消息提示您没有权限,那么客户经理需要更改允许连接 C2C 设备的权限,或将您添加到一个拥有这些权限的角色中。
  • 您已连接了一台设备:在连接第一台设备之后,蓝色的“添加新设备”大按钮会消失,此时,您需要进入 C2C Connections 面板右上角的三点菜单中。
  • 无效客户端错误:当您向我们提供的设备信息与我们记录中的任何信息都不匹配时,会返回 invalid_client。这很可能意味着您的 client_secret 不正确。
  • 错误请求错误:当请求数据格式有误时,会返回 bad_request。请仔细检查您是否拼错了某个字段名称,或者忘记添加必填字段。

下一步

如果您还没有联系我们的团队,我们鼓励您这样做,然后继续阅读下一份指南:LINK。我们期待收到您的回复!


暂存区

待办事项

为无法生成动态 QR 代码的合作伙伴添加应急方案

即:让他们显示“前往 **verification_uri** 输入此代码”作为备用方案