方法:認証

はじめに

このガイドでは、Frame.io プロジェクトでの Camera to Cloud(C2C)デバイスの認証と認証プロセスを説明します。標準的な手動コード入力方法と、最適なユーザーエクスペリエンスのための拡張 QR コードペアリングアプローチの両方を説明します。

何が必要ですか?

まだの場合は、実装を開始する前にガイドをレビューしてください。統合を識別するために、チームからclient_secretを受け取っているはずです。そうでない場合は、C2C エコシステムのこの紹介を参照し、チームにお問い合わせください。

URL と QR コードペアリングの前提条件

URL と QR コードペアリングを実装するには、これらの要件を満たすことを確認してください:

  • デバイスの互換性:ペアリングプロセス中にデバイスが URL/QR コード生成をサポートしていることを確認してください。

認証フローの説明

ユーザーの視点から認証フローを理解するには、これらのリソースを参照してください:

この認証プロセスは実装要件を最小限に抑えます。次のことを行う必要はありません:

  • web ブラウザーへのリダイレクト(URL コードペアリングを使用している場合を除く)
  • Frame.io ユーザー認証の処理
  • アカウント/プロジェクト選択インターフェイスの提示
  • 基本的な情報表示を超えた複雑な UI コンポーネントの開発

URL コードペアリングによるユーザーエクスペリエンスの向上

現代のユーザーは効率的なデバイスインタラクションを期待します。現在の手動ペアリングプロセスは適切に機能しますが、最適化できます。

Netflix や Disney+ などのストリーミングサービスと同様に、URL と QR コードペアリングを実装することで、プロセスを大幅に合理化し、入力エラーを最小限に抑え、ペアリング時間を短縮できます。

デバイス識別子(client_id)

各物理デバイスには、ユーザーのプロジェクト内での接続トラッキングのための固有の識別子が必要です。

デバイスの場合、この識別子はclient_idであり、認証時に不可欠です。実装時には、デバイスのシリアル番号、UUID、またはその他の固有の文字列など、適切な識別子ソースを検討してください。Appleデバイスで統合を行う場合は、デバイスの再起動時でも一貫した固有の永続的UUIDを使用することをお勧めします。個人識別情報については注意してください。ユーザーのメールアドレスは適切なclient_id値ではありません。

さらに、識別子を制御できることを確認してください。デバイスの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

URLコードペアリングの有効化

URLコードペアリングの場合は、追加のヘッダーで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 URL pairing
--form 'client_id=[client_id]' \
--form 'client_secret=[client_secret]' \
--form 'scope=asset_create offline' \
| python -m json.tool

**注意:**これらの認証エンドポイントは、JSONではなく、フォームデータのみを受け入れます。認証後、他のエンドポイントは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"
}

URL ペアリング応答

{
"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に手動入力する6桁のコード。
  • verification_uri:QRスキャンができない場合の手動入力用のベースURL。
  • verification_uri_complete:ペアリングコードを含む完全なURL。モバイルアプリ内でのハイパーリンクやQRコード生成に使用し、ユーザーをペアリングインターフェイスへスムーズにナビゲートします。

ユーザーへのQRコード表示

verification_uri_completeを使用して、ユーザーがスキャンできるようにデバイス画面にQRコードを生成・表示し、効率的なペアリングを促進します。

例:QRコードが表示されたデバイス画面

<img alt=“デバイスQRコードペアリング画面の例” src=“file:docs/pages/c2c/static/images/qr_code_example.png”>常にフォールバックオプションを提供してください:QRスキャンができない場合の手動入力用にuser_codeverification_uriを表示します。または、モバイルスキャン用の静的QRコードとしてverification_uriを表示することも検討してください。モバイルアプリ統合では、アプリを実行しているデバイスからはQRコードをスキャンできないため、verification_uri_completeをタップ可能なハイパーリンクとして含めてください。

ステップ2:ユーザー認証の投票

ペアリングコードまたはURLコードを提供した後、このリクエストでユーザーの入力を検証します:

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 で使用したのと同じ識別子。
  • device_code:以前に返された device_code 値。
  • grant_type:OAuth 付与タイプ識別子。この実装では常に urn:ietf:params:oauth:grant-type:device_code

初回の調査試行では通常次が返されます:

{
"error": "authorization_pending"
}

この致命的でないエラーは、ユーザーがコード入力を完了していないことを示します。完了まで調査を続けます。

**iOS アプリデバイスに関するノーツ:**ユーザーがペアリングコードを入力するために Frame.io iOS アプリに切り替えると、アプリケーションが背景に移行する可能性があります。applicationDidBecomeActive などでアプリケーションが再びプライマリになったら、認証流量を継続できるよう調査を再開し、ユーザーにペアリングの再起動を求める必要がなくなります。

次を受信した場合:

{
"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 バックエンドアクセスのための認証資格情報。今後の API 要求のヘッダーに必要です。
  • expires_in:アクセストークンの有効期間(秒単位)。この期間後は更新が必要です。
  • refresh_token:アクセストークン管理に使用。主に認証更新用ですが、取り消しにも適用されます。
  • token_type:C2C API 実装では常に bearer。アクションは不要です。

ステップをまとめる

デバイスコードの期限切れの可能性を処理しながら、これらの API 呼び出しを 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 there was some other error, raise it.
44 raise error
45 else:
46 # If there was no error, we have our authorization!
47 return authorization
48
49 # If we get here, our pairing codes expired. Let's try again.
50 print("\nPairing code expired. Generating a new one...")

**ノーツ:**外側のループは、ペアリングコードが期限切れになり新しいコードが必要になる場合を処理します。

最後のステップとして、Frame.io からプロジェクト情報を取得して表示し、意図したプロジェクトへのペアリングが成功したことを確認します。これについては次のチュートリアルで説明します。

ペアリング用 QR コードの作成と表示

URL/QR コードペアリングを実装する場合、応答の verification_uri_complete 値から QR コードを生成する必要があります。人気のライブラリを使用した各プログラミング言語の例を以下に示します:

qrcodeを使用したPythonの例

Python
1import qrcode
2from PIL import Image
3import io
4
5def generate_qr_code(verification_uri_complete, size=250):
6 """
7 Generate a QR code from the verification_uri_complete URL.
8
9 Args:
10 verification_uri_complete (str): The complete verification URI returned by Frame.io
11 size (int, optional): Size of the QR code in pixels. Defaults to 250.
12
13 Returns:
14 PIL.Image: QR code image that can be displayed or saved
15 """
16 qr = qrcode.QRCode(
17 version=1,
18 error_correction=qrcode.constants.ERROR_CORRECT_L,
19 box_size=10,
20 border=4,
21 )
22 qr.add_data(verification_uri_complete)
23 qr.make(fit=True)
24
25 img = qr.make_image(fill_color="black", back_color="white")
26
27 # Resize the image if needed
28 img = img.resize((size, size))
29 return img
30
31# Example usage in authorization flow
32def display_qr_for_pairing(pairing_codes):
33 """
34 Generate and display QR code along with manual pairing instructions.
35 """
36 if hasattr(pairing_codes, 'verification_uri_complete'):
37 # Generate QR code from the verification URI
38 qr_img = generate_qr_code(pairing_codes.verification_uri_complete)
39
40 # Display the QR code on screen
41 # For GUI applications like Tkinter, PyQt, etc.
42 # display_image(qr_img)
43
44 # For headless devices or testing, save to file
45 qr_img.save("frame_io_pairing_qr.png")
46
47 print(f"Scan the QR code or visit: {pairing_codes.verification_uri}")
48 print(f"Manual code: {pairing_codes.user_code}")
49 else:
50 # Fallback for devices that received traditional pairing response
51 print(f"Enter code on Frame.io: {pairing_codes.user_code}")

JavaScript の例(webまたはElectron)

1import QRCode from 'qrcode';
2
3/**
4 * Generate and display a QR code from the verification URI
5 * @param {string} verificationUriComplete - The complete verification URI from Frame.io
6 * @param {string} elementId - ID of the HTML element to display the QR code in
7 */
8function displayQRCode(verificationUriComplete, elementId = 'qrcode-container') {
9 const element = document.getElementById(elementId);
10
11 if (!element) {
12 console.error(`Element with ID ${elementId} not found`);
13 return;
14 }
15
16 // Clear any existing content
17 element.innerHTML = '';
18
19 // Generate QR code
20 QRCode.toCanvas(element, verificationUriComplete, { width: 250 }, function(error) {
21 if (error) {
22 console.error('Error generating QR code:', error);
23 // Fallback to displaying the URL as a link
24 element.innerHTML = `<a href="${verificationUriComplete}" target="_blank">Click here to pair</a>`;
25 }
26 });
27
28 // Also display manual pairing information
29 const manualInfoDiv = document.createElement('div');
30 manualInfoDiv.innerHTML = `
31 <p>Scan the QR code or <a href="${verificationUriComplete}" target="_blank">click here</a> to pair your device.</p>
32 <p>Manual code: ${userCode}</p>
33 `;
34 element.parentNode.appendChild(manualInfoDiv);
35}
36
37// Example usage in authorization flow
38async function requestDeviceCode() {
39 try {
40 const response = await fetch('https://api.frame.io/v2/auth/device/code', {
41 method: 'POST',
42 headers: {
43 'x-client-version': '2.0.0',
44 'x-client-platypus-enabled': 'true'
45 },
46 body: new URLSearchParams({
47 'client_id': YOUR_CLIENT_ID,
48 'client_secret': YOUR_CLIENT_SECRET,
49 'scope': 'asset_create offline'
50 })
51 });
52
53 const data = await response.json();
54
55 if (data.verification_uri_complete) {
56 displayQRCode(data.verification_uri_complete);
57 window.userCode = data.user_code; // Store for display purposes
58 } else {
59 // Fallback for traditional pairing
60 displayManualPairingCode(data.user_code);
61 }
62
63 // Begin polling for authorization
64 beginPollingForAuthorization(data.device_code, data.interval);
65
66 } catch (error) {
67 console.error('Error requesting device code:', error);
68 }
69}

Androidの例(Java)

1import android.graphics.Bitmap;
2import android.widget.ImageView;
3import com.google.zxing.BarcodeFormat;
4import com.google.zxing.MultiFormatWriter;
5import com.google.zxing.common.BitMatrix;
6import com.journeyapps.barcodescanner.BarcodeEncoder;
7
8public void generateAndDisplayQRCode(String verificationUriComplete, ImageView qrCodeImageView) {
9 try {
10 MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
11 BitMatrix bitMatrix = multiFormatWriter.encode(verificationUriComplete,
12 BarcodeFormat.QR_CODE, 250, 250);
13 BarcodeEncoder barcodeEncoder = new BarcodeEncoder();
14 Bitmap bitmap = barcodeEncoder.createBitmap(bitMatrix);
15
16 // Display in ImageView
17 qrCodeImageView.setImageBitmap(bitmap);
18
19 } catch (Exception e) {
20 e.printStackTrace();
21 // Fallback to displaying the URL as text
22 }
23}

iOSの例(Swift)

1import UIKit
2import CoreImage
3
4func generateQRCode(from string: String) -> UIImage? {
5 let data = string.data(using: String.Encoding.utf8)
6
7 if let filter = CIFilter(name: "CIQRCodeGenerator") {
8 filter.setValue(data, forKey: "inputMessage")
9 filter.setValue("H", forKey: "inputCorrectionLevel")
10
11 if let outputImage = filter.outputImage {
12 // Scale the image
13 let transform = CGAffineTransform(scaleX: 10, y: 10)
14 let scaledImage = outputImage.transformed(by: transform)
15
16 // Convert to UIImage
17 let context = CIContext()
18 if let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent) {
19 return UIImage(cgImage: cgImage)
20 }
21 }
22 }
23
24 return nil
25}
26
27// Usage in your view controller
28func displayPairingQRCode(verificationUriComplete: String) {
29 if let qrCodeImage = generateQRCode(from: verificationUriComplete) {
30 qrCodeImageView.image = qrCodeImage
31
32 // Also show manual pairing information
33 pairingInstructionsLabel.text = "Scan the QR code or enter code manually"
34 pairingCodeLabel.text = userCode
35 } else {
36 // Fallback to manual code display
37 pairingInstructionsLabel.text = "Enter this code on Frame.io:"
38 pairingCodeLabel.text = userCode
39 }
40}

QR コード表示のベストプラクティス

QR コードペアリングを実装する際は、最適なユーザーエクスペリエンスのために以下のガイドラインを検討してください:

  1. 最適なサイズ:信頼性のあるスキャンのため、QR コードは最低200〜250ピクセル四方で表示してください。

  2. コントラスト:QR コードと背景の間に高いコントラストを確保してください(白背景に黒が理想的)。

  3. エラー訂正:コードの密度と信頼性のバランスを取るため、中程度のエラー訂正レベル(LまたはM)を使用してください。

  4. 明確な指示:「デバイスをペアリングするには、スマートフォンのカメラでこのコードをスキャンしてください」など、コードのスキャン方法について明確なガイダンスを提供してください。

  5. 複数のオプション:フォールバックとして、QR コードと併せて手動ペアリングコードを常に提供してください:

Scan to pair:
[QR CODE]
Or enter code manually: 573131
  1. モバイルアプリのハイパーリンク:統合がモバイルアプリケーションの場合、同一デバイスからQR コードをスキャンできないため、verification_uri_completeをタップ可能なリンクとして含めてください。

  2. テスト:信頼性のあるスキャンを確保するため、様々なデバイスと照明条件でQR コードをテストしてください。

<img alt=“QR コード表示の例” src=“file:docs/pages/c2c/static/images/qr_code_example.png”>

トラブルシューティング

問題が発生した場合は、以下の一般的なシナリオと解決策を参照してください:

  • 「デバイスを接続」ボタンが表示されない:C2C管理パネルにアクセスする際、これは以下を示している可能性があります:

  • 権限不足:権限メッセージが表示される場合は、アドビ担当営業または販売店に連絡して権限を調整するか、適切なロールを割り当ててもらってください。* 既存のデバイス接続:1つのデバイスを接続した後、メインの「新しいデバイスを追加」ボタンは、C2C接続パネルの右上隅にある3点メニューに置き換えられます。

  • 無効なクライアントエラーinvalid_client応答は、通常間違ったclient_secretによる、デバイス情報の不一致を示します。

  • 不正なリクエストエラーbad_request応答は、不正な形式のリクエストデータを示します。フィールド名を確認し、すべての必須フィールドが含まれていることを確認してください。

問題がここで解決されない場合は、このトラブルシューティングセクションを改善できるよう、エクスペリエンスを共有してください。

次のステップ

チームへの連絡をお勧めします。認証管理ガイドに進んでください。フィードバックをお待ちしております!