Instruções: Autorizar

Introdução

Este guia demonstra o processo de autenticação e autorização para dispositivos Camera to Cloud (C2C) em um projeto Frame.io. Vamos explorar tanto o método padrão de inserção manual de código quanto a abordagem aprimorada de emparelhamento via QR Code para otimizar a experiência do usuário.

O que vou precisar?

Revise o guia Antes de começar a implementação se ainda não fez isso. Você deve ter recebido um client_secret da nossa equipe para identificar sua integração. Se não recebeu, consulte esta introdução ao ecossistema C2C e entre em contato com nossa equipe.

Pré-requisitos para emparelhamento por URL e QR Code

Para implementar o emparelhamento por URL e QR Code, certifique-se de atender aos requisitos:

  • Compatibilidade de dispositivos: verifique se o dispositivo suporta geração de URL/QR Code durante o processo de emparelhamento.

Como funciona o fluxo de autorização

Para entender o fluxo de autorização da perspectiva do usuário, consulte estes recursos:

Este processo de autorização minimiza os requisitos de implementação. Você não precisará:

  • Redirecionar para navegadores da web (a menos que use o emparelhamento por código URL)
  • Lidar com autenticação de usuário do Frame.io
  • Apresentar interfaces de seleção de conta/projeto
  • Desenvolver componentes de interface complexos além de exibições básicas de informações

Aprimorando a experiência do usuário com emparelhamento por URL Code

Usuários modernos esperam interações eficientes com dispositivos. Embora o processo atual de emparelhamento manual funcione adequadamente, ele pode ser otimizado.

Ao implementar o emparelhamento por URL e QR Code, semelhante aos serviços de streaming como Netflix ou Disney+, podemos simplificar significativamente o processo, minimizar erros de entrada e reduzir o tempo de emparelhamento.

Identificação do dispositivo (client_id)

Cada dispositivo físico requer um identificador exclusivo para rastreamento de conexão dentro do projeto de um usuário.

Para dispositivos, esse identificador é o client_id, que é essencial durante a autorização. Ao implementar, considere origens de identificador apropriadas, como números de série do dispositivo, UUIDs ou outras strings exclusivas. Se você estiver integrando em um dispositivo Apple, recomendamos usar um UUID persistente e exclusivo que seja consistente entre reinicializações do dispositivo. Tenha cuidado com informações pessoais identificáveis. Endereços de email do usuário não são valores client_id adequados.

Além disso, certifique-se de controlar o identificador. Endereços MAC do dispositivo são inadequados, pois não são de propriedade do seu software e podem constituir informações pessoais identificáveis.

Se você precisar de orientação sobre como selecionar um identificador adequado, nossa equipe pode ajudar a determinar um valor adequado que simplifique a integração.

Etapa 1: solicitar um código de dispositivo

Para começar a implementação, solicite um código de dispositivo através do ponto de acesso /v2/auth/device/code:

Método de emparelhamento tradicional

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

Ativação do emparelhamento por URL Code

Para emparelhamento por código URL, modifique a chamada de API com cabeçalhos adicionais:

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

Observação: esses pontos de acesso de autenticação aceitam exclusivamente dados de formulário, não JSON. Pós-autenticação, outros pontos de acesso aceitarão conteúdos JSON, mas pontos de acesso de autenticação rejeitarão solicitações JSON.

Parâmetros do conteúdo

  • client_id: o identificador exclusivo para seu dispositivo físico. Isso deve ser garantidamente exclusivo, como um número de série ou UUID.

  • client_secret: fornecido pelo suporte do Frame.io para identificar o modelo do seu dispositivo. Esse valor confidencial deve permanecer protegido dos usuários e criptografado quando armazenado.

  • scope: as permissões solicitadas, separadas por espaços. Os dispositivos podem solicitar:

  • asset_create: permite a criação e o upload de ativos. * offline: permite a atualização de autorização por meio do token de atualização. Sem esse escopo, os usuários precisariam autorizar novamente o dispositivo a cada 8 horas, já que os tokens de autorização expiram.

Em implementações práticas, os dispositivos normalmente solicitam ambos os escopos.

Entender a resposta da API

A solicitação gera uma resposta similar a:

Resposta de emparelhamento tradicional

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

Resposta de emparelhamento por 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"
}

Detalhamento da resposta

  • device_code: este identificador interno deve permanecer oculto dos usuários e identifica a solicitação de autorização durante o polling.
  • expires_in: o período de validade do código em segundos.
  • interval: o intervalo de polling recomendado em segundos.
  • name: o identificador do dispositivo de conexão.
  • user_code: o código de seis dígitos para entrada manual no Frame.io para emparelhamento do dispositivo.
  • verification_uri: o URL base para entrada manual se a leitura do QR Code não estiver disponível.
  • verification_uri_complete: o URL completo que contém o código de emparelhamento, destinado para criar hiperlink em um aplicativo para dispositivos móveis ou geração de QR Code para simplificar a navegação do usuário para a interface de emparelhamento.

Exibir o QR Code para o usuário

Usando o verification_uri_complete, gere e exiba um QR Code na tela do dispositivo para o usuário escanear, facilitando o emparelhamento eficiente.

Exemplo: tela do dispositivo com QR Code exibido

Exemplo de tela de emparelhamento de QR Code do dispositivo Sempre forneça opções de fallback: exiba o user_code e o verification_uri para entrada manual quando a leitura do QR Code não for possível. Como alternativa, considere exibir o verification_uri como um QR Code estático para leitura móvel. Para integrações de aplicativo para dispositivos móveis, inclua o verification_uri_complete como um hiperlink clicável, já que os usuários não podem escanear QR Codes do dispositivo que executa o aplicativo.

Etapa 2: polling para autorização do usuário

Depois de fornecer o código de emparelhamento ou código de URL, verifique a entrada do usuário com esta solicitação:

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

Parâmetros do conteúdo

  • client_id: o mesmo identificador usado na Etapa 1.
  • device_code: o valor device_code retornado anteriormente.
  • grant_type: o identificador do tipo de concessão OAuth, consistentemente urn:ietf:params:oauth:grant-type:device_code para esta implementação.

As tentativas iniciais de polling normalmente retornam:

{
"error": "authorization_pending"
}

Este erro não fatal indica que o usuário não concluiu a entrada do código. Continue a enquete até a conclusão.

Observação para dispositivos com app iOS: se o usuário alternar para o app iOS do Frame.io para inserir o código de emparelhamento, o app pode ir para o fundo. Quando o app ficar ativo novamente, como em applicationDidBecomeActive, retome a enquete para que o fluxo de autorização possa continuar sem exigir que o usuário reinicie o emparelhamento.

Se receber:

{
"error": "expired_token"
}

O código expirou antes da entrada do usuário. Gere um novo código/QR Code via Etapa 1, apresente-o ao usuário e retome o polling.

A autorização bem-sucedida produz:

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

Parabéns por autorizar com sucesso o dispositivo Camera to Cloud!

Vamos analisar esta resposta:

  • access_token: sua credencial de autenticação para acesso ao back-end do Frame.io, necessária em cabeçalhos para futuras chamadas de API.
  • expires_in: o período de validade do token de acesso em segundos, após o qual a atualização é necessária.
  • refresh_token: usado para gerenciamento de tokens de acesso, principalmente para atualizar autorizações, mas também aplicável para revogações.
  • token_type: consistentemente bearer para implementações de API C2C, não requerendo ação.

Reunir as etapas

Agora vamos implementar essas chamadas de API em pseudocódigo similar ao Python, lidando com potencial expiração do código do dispositivo:

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

Observação: o loop externo lida com casos onde códigos de emparelhamento expiram e novos códigos são necessários.

Como etapa final, recupere e exiba informações do projeto do Frame.io para confirmar o emparelhamento bem-sucedido ao projeto pretendido. Abordaremos isso no próximo tutorial.

Criação e exibição de QR Codes para emparelhamento

Ao implementar o emparelhamento por URL/QR Code, você precisará gerar um QR Code a partir do valor verification_uri_complete na resposta. Aqui estão exemplos usando bibliotecas populares em diferentes linguagens de programação:

Exemplo Python usando 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}")

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

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

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

Práticas recomendadas para exibição de QR Code

Ao implementar o emparelhamento por QR Code, considere estas diretrizes para obter a melhor experiência do usuário:

  1. Tamanho ideal: exiba QR Codes com pelo menos 200 a 250 pixels quadrados para leitura confiável.

  2. Contraste: garanta alto contraste entre o QR Code e o fundo (preto sobre branco é o ideal).

  3. Correção de erros: use níveis moderados de correção de erros (L ou M) para equilibrar densidade de código e confiabilidade.

  4. Instruções claras: forneça orientação clara sobre como escanear o código, como “Escaneie este código com a câmera do smartphone para emparelhar o dispositivo”.

  5. Várias opções: sempre forneça o código de emparelhamento manual junto ao QR Code como alternativa:

Scan to pair:
[QR CODE]
Or enter code manually: 573131
  1. Hiperlink para aplicativos para dispositivos móveis: se sua integração for um aplicativo para dispositivos móveis, inclua o verification_uri_complete como um link tocável, já que os usuários não conseguem escanear um QR code no mesmo dispositivo.

  2. Testar: teste os QR Codes com vários dispositivos e condições de iluminação para garantir leitura confiável.

Exemplo de exibição de QR Code

Solução de problemas

Se você encontrar problemas, consulte estes cenários comuns e soluções:

  • Botão “Conectar dispositivo” não visível: ao acessar o painel de gerenciamento C2C, isso pode indicar:

  • Permissões insuficientes: se você vir uma mensagem de permissões, entre em contato com o gerente de conta para ajustar as permissões ou atribuir uma função apropriada. * Conexão de dispositivo existente: depois de conectar um dispositivo, o botão principal “Adicionar novo dispositivo” é substituído por um menu de três pontos no canto superior direito do painel Conexões C2C.

  • Erro de cliente inválido: uma resposta invalid_client indica incompatibilidade de informações do dispositivo, geralmente devido a um client_secret incorreto.

  • Erro de solicitação inválida: uma resposta bad_request indica dados de solicitação inválidos.Verifique os nomes dos campos e confirme se todos os campos obrigatórios estão incluídos.

Se o problema não for resolvido aqui, compartilhe sua experiência para que possamos aprimorar esta seção de solução de problemas.

Próximas etapas

Recomendamos que você entre em contato com nossa equipe e consulte o guia de gerenciamento de autorizações. Aguardamos seus comentários!