Comment octroyer des autorisations

Présentation

Ce guide présente le processus d’authentification et d’autorisation pour les appareils Camera to Cloud (C2C) sur un projet Frame.io. Nous explorerons à la fois la méthode standard de saisie manuelle de code et l’approche améliorée de couplage par code QR pour une expérience client optimale.

De quoi ai-je besoin ?

Si ce n’est pas déjà fait, consultez le guide Avant de commencer l’implémentation. Vous devriez avoir reçu une valeur client_secret de notre équipe pour identifier votre intégration. Si ce n’est pas le cas, consultez cette introduction au réseau C2C et contactez notre équipe.

Conditions préalables pour le couplage par URL et code QR

Pour mettre en œuvre le couplage par URL et code QR, vérifiez que vous respectez les exigences suivantes :

  • Compatibilité de l’appareil : vérifiez que l’appareil prend en charge la génération d’URL/code QR pendant le processus de couplage.

Exploration du flux d’autorisation

Pour comprendre le flux d’autorisation du point de vue de l’utilisateur, consultez ces ressources :

Ce processus d’autorisation minimise les exigences d’implémentation. Vous n’aurez pas besoin de :

  • rediriger vers les navigateurs web (sauf lors du couplage par code URL) ;
  • gérer l’authentification de l’utilisateur Frame.io ;
  • présenter les interfaces de sélection de compte/projet ;
  • développer des composants d’interface utilisateur complexes au-delà des affichages d’informations de base.

Amélioration de l’expérience client avec le couplage par code URL

Les utilisateurs modernes s’attendent à des interactions efficaces avec les appareils. Bien que le processus de couplage manuel actuel fonctionne correctement, il peut être optimisé.

En implémentant le couplage par URL et code QR (semblable aux services de streaming comme Netflix ou Disney+), nous pouvons considérablement rationaliser le processus, minimiser les erreurs de saisie et raccourcir le temps de couplage.

Identification de l’appareil (client_id)

Chaque appareil physique nécessite un identifiant unique pour le suivi des connexions dans le projet d’un utilisateur.

Pour les appareils, cet identifiant correspond au paramètre client_id, qui est essentiel lors de l’autorisation. Lors de l’implémentation, considérez des sources d’identifiants appropriées telles que les numéros de série d’appareil, les UUID ou d’autres chaînes uniques. Si vous effectuez l’intégration sur un appareil Apple, nous vous recommandons d’utiliser un UUID persistant unique qui reste cohérent lors des redémarrages de l’appareil. Faites preuve de prudence concernant les informations personnellement identifiables. Les adresses e-mail des utilisateurs ne sont pas des valeurs client_id appropriées.

Assurez-vous également de contrôler l’identifiant. Les adresses MAC des appareils ne conviennent pas, car elles n’appartiennent pas à votre logiciel et peuvent constituer des informations personnellement identifiables.

Si vous avez besoin de conseils pour choisir un identifiant approprié, notre équipe peut vous aider à déterminer une valeur adaptée qui simplifie l’intégration.

Étape 1 : demande d’un code d’appareil

Pour commencer l’implémentation, demandez un code d’appareil via le point d’entrée /v2/auth/device/code :

Méthode de couplage traditionnelle

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

Activation du couplage par code URL

Pour le couplage par code URL, modifiez l’appel API avec des en-têtes supplémentaires :

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

Remarque : ces points d’entrée d’authentification acceptent exclusivement les données de formulaire, pas JSON. Après l’authentification, les autres points d’entrée accepteront les payloads JSON, mais les points d’entrée d’authentification rejetteront les requêtes JSON.

Paramètres de payload

  • client_id : identifiant unique pour votre appareil physique. Il doit absolument être unique, par exemple un numéro de série ou UUID.

  • client_secret : fourni par le support Frame.io pour identifier votre modèle d’appareil. Cette valeur confidentielle doit rester protégée des utilisateurs et chiffrée lors du stockage.

  • scope : autorisations demandées, séparées par des espaces. Les appareils peuvent demander :

  • asset_create : active la création et le chargement de ressources. * offline : permet l’actualisation de l’autorisation via le jeton d’actualisation. Sans cette portée, les utilisateurs devraient réautoriser leur appareil toutes les 8 heures, car les jetons d’autorisation expirent.

Dans les implémentations pratiques, les appareils demandent généralement les deux portées.

Comprendre la réponse de l’API

La demande génère une réponse semblable à :

Réponse de couplage traditionnel

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

Réponse de couplage par 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"
}

Décomposition de la réponse

  • device_code : cet identifiant interne ne doit pas être visible pour les utilisateurs ; il identifie la demande d’autorisation lors de l’enquête.
  • expires_in : période de validité du code en secondes.
  • interval : intervalle d’enquête recommandé en secondes.
  • name : identifiant de l’appareil de connexion.
  • user_code : code à six chiffres pour la saisie manuelle dans Frame.io pour le couplage de l’appareil.
  • verification_uri : URL de base pour la saisie manuelle s’il est impossible de scanner le code QR.
  • verification_uri_complete : URL complète contenant le code de couplage, destinée aux liens hypertexte dans une application mobile ou à la génération de code QR pour simplifier la navigation utilisateur vers l’interface de couplage.

Affichage du code QR pour l’utilisateur

En utilisant verification_uri_complete, générez et affichez un code QR sur l’écran de l’appareil pour que l’utilisateur puisse le scanner, facilitant ainsi un couplage efficace.

Exemple : écran d’appareil avec code QR affiché

Exemple d’écran de couplage par code QR Fournissez toujours des options de secours : affichez les paramètres user_code et verification_uri pour la saisie manuelle lorsque le code QR ne peut pas être scanné. Vous pouvez également afficher le paramètre verification_uri comme un code QR statique pour la numérisation mobile. Pour les intégrations d’application mobile, incluez verification_uri_complete comme un lien hypertexte cliquable, car les utilisateurs ne peuvent pas scanner les codes QR depuis l’appareil exécutant l’application.

Étape 2 : demande d’autorisation utilisateur

Après avoir fourni le code de couplage ou le code URL, vérifiez la saisie utilisateur avec cette requête :

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

Paramètres de payload

  • client_id : même identifiant que celui utilisé à l’étape 1.
  • device_code : valeur device_code renvoyée précédemment.
  • grant_type : identifiant de type d’octroi OAuth, toujours urn:ietf:params:oauth:grant-type:device_code pour cette implémentation.

Les tentatives d’enquête initiales renvoient généralement :

{
"error": "authorization_pending"
}

Cette erreur non fatale indique que l’utilisateur n’a pas terminé la saisie du code. Continuez l’enquête jusqu’à la fin.

Remarque pour les appareils iOS : si l’utilisateur bascule vers l’application iOS Frame.io pour saisir le code de couplage, l’application peut passer en arrière-plan. Lorsque l’application redevient active, par exemple dans applicationDidBecomeActive, reprenez l’enquête pour que le flux d’autorisation puisse continuer sans que l’utilisateur ait besoin de redémarrer le couplage.

Si vous recevez :

{
"error": "expired_token"
}

Le code a expiré avant la saisie utilisateur. Générez un nouveau code/code QR via l’étape 1, présentez-le à l’utilisateur et reprenez l’enquête.

Une autorisation réussie produit :

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

Votre appareil Camera to Cloud a bien été autorisé !

Examinons cette réponse :

  • access_token : vos informations d’identification d’authentification pour l’accès au backend Frame.io, requis dans les en-têtes pour les futures requêtes API.
  • expires_in : la période de validité du jeton d’accès en secondes, après laquelle l’actualisation est nécessaire.
  • refresh_token : utilisé pour la gestion des jetons d’accès, principalement pour actualiser l’autorisation mais aussi applicable pour la révocation.
  • token_type : toujours bearer pour les implémentations d’API C2C, ne nécessitant aucune action.

Regrouper toutes les étapes

Implémentons maintenant ces appels API en pseudocode de type Python, en gérant l’expiration potentielle du code d’appareil :

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...")

Remarque : la boucle externe gère les cas où les codes de couplage expirent et où de nouveaux codes sont requis.

Comme étape finale, récupérez et affichez les informations de projet depuis Frame.io pour confirmer le couplage réussi au projet prévu. Nous aborderons ce point dans le tutoriel suivant.

Création et affichage de codes QR pour le couplage

Lors de l’implémentation du couplage URL/code QR, vous devez générer un code QR à partir de la valeur verification_uri_complete dans la réponse. Voici des exemples utilisant des bibliothèques populaires dans différents langages de programmation :

Exemple Python avec qrcode

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

Exemple JavaScript (web ou 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}

Exemple 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}

Exemple 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}

Bonnes pratiques pour l’affichage de codes QR

Lors de l’implémentation du couplage par code QR, tenez compte de ces recommandations pour une expérience client optimale :

  1. Taille optimale : affichez des codes QR d’au moins 200-250 pixels carrés pour une lecture fiable.

  2. Contraste : assurez-vous d’un contraste élevé entre le code QR et l’arrière-plan (noir sur blanc est idéal).

  3. Correction d’erreurs : utilisez des niveaux de correction d’erreurs modérés (L ou M) afin de trouver un juste équilibre entre la densité du code et sa fiabilité.

  4. Instructions claires : fournissez des instructions claires sur la façon de scanner le code, par exemple « Scannez ce code avec l’appareil photo de votre smartphone pour coupler votre appareil. »

  5. Options multiples : fournissez toujours le code de couplage manuel avec le code QR comme solution de secours :

Scan to pair:
[QR CODE]
Or enter code manually: 573131
  1. Lien hypertexte pour Mobile Apps : si votre intégration est une application mobile, incluez verification_uri_complete comme lien cliquable, car les utilisateurs ne peuvent pas scanner un code QR depuis le même appareil.

  2. Tests : testez les codes QR avec différents appareils et conditions d’éclairage pour assurer une lecture fiable.

Exemple d’affichage de code QR

Résolution des problèmes

Si vous rencontrez des problèmes, consultez les scénarios courants suivants et leurs solutions :

  • Bouton « Connecter un appareil » non visible : lors de l’accès au panneau de gestion C2C, cette erreur peut indiquer :

  • Autorisations insuffisantes : si un message d’autorisations s’affiche, contactez le gestionnaire de compte pour ajuster les autorisations ou attribuer un rôle approprié. * Connexion d’appareil existante : après avoir connecté un appareil, le bouton principal « Ajouter un nouvel appareil » est remplacé par un menu à trois points dans le coin supérieur droit du panneau Connexions C2C.

  • Erreur de client non valide : une réponse invalid_client indique une incompatibilité des informations de l’appareil, généralement due à un paramètre client_secret incorrect.

  • Erreur de demande incorrecte : une réponse bad_request indique des données de demande incorrectement formées. Vérifiez les noms des champs et assurez-vous que tous les champs requis sont inclus.

Si votre problème n’est pas traité ici, partagez votre expérience afin que nous puissions améliorer cette section de résolution des problèmes.

Étapes suivantes

Nous vous invitons à contacter notre équipe et à consulter le guide de gestion des autorisations. Nous attendons vos commentaires avec impatience !