Fluxo de Aplicativo Nativo
Use o fluxo de aplicativo nativo para integrações que agem em nome de um usuário conectado a partir da própria máquina dele, como um aplicativo de desktop, uma CLI ou um plugin de CAD. Ele usa Authorization Code com PKCE, um redirecionamento loopback localhost e nenhum segredo de cliente. Este guia mostra a configuração da criação do aplicativo OAuth até a primeira chamada à API.
Consulte primeiro o guia Primeiros passos se você ainda não conhece os pré-requisitos, o acesso de rede e o modelo de segurança.
O que você fará
Seção intitulada “O que você fará”- Criar um aplicativo OAuth: Registre um aplicativo nativo no Prevu3D e obtenha um Client ID
- Configurar o acesso do usuário: Garanta que o usuário que fará login consiga alcançar os dados de que precisa
- Autorizar com PKCE: Envie o usuário à página de consentimento no navegador
- Trocar o código por um token: Troque o código de autorização por um token de acesso
- Encontrar sua URL da API: Descubra a URL base da sua organização (ela varia por região)
- Fazer sua primeira chamada: Teste a conexão com uma requisição simples
Etapa 1: criar seu aplicativo OAuth
Seção intitulada “Etapa 1: criar seu aplicativo OAuth”- Faça login na Plataforma Prevu3D.
- Vá em Settings → OAuth.
- Clique para criar um novo aplicativo.
- Ative o Authorization Code flow.
- Ative Native Application. A URI de redirecionamento é fixada em
http://localhost. - Deixe o segredo de cliente desativado. Aplicativos nativos não usam segredo.
- Copie e armazene com segurança seu Client ID. Você precisará dele em cada autorização.
Etapa 2: configurar o acesso do usuário
Seção intitulada “Etapa 2: configurar o acesso do usuário”O fluxo nativo chama a API como o usuário conectado, não como um usuário de serviço. Isso cobre as camadas 2 e 3 do modelo de segurança: quais nós o usuário pode ver (acesso ao conteúdo) e o que ele pode fazer com eles (acesso por função/permissão).
- Garanta que o usuário que fará login tenha acesso ao conteúdo dos nós (organizações, divisões, sites etc.) que seu caso de uso exige.
- Garanta que o usuário tenha uma função nesses nós com as permissões de que sua integração precisa (ler, editar, gerenciar etc.).
Na tela de consentimento, o usuário também seleciona qual organização autorizar. Os escopos que o usuário aprova ali configuram a camada 1.
Etapa 3: autorizar com PKCE
Seção intitulada “Etapa 3: autorizar com PKCE”Aplicativos nativos não conseguem guardar um segredo, então o fluxo usa PKCE para proteger o código de autorização. Antes de abrir a página de consentimento, gere três valores:
| Valor | Como |
|---|---|
code_verifier | String aleatória, de 43 a 128 caracteres |
code_challenge | BASE64URL(SHA256(code_verifier)) sem preenchimento |
state | String aleatória; valide-a quando o redirecionamento retornar |
Inicie um servidor loopback local em uma porta livre e, em seguida, abra o navegador do usuário na página de consentimento.
URL de consentimento: https://cloud.prevu3d.com/oauth
Parâmetros de consulta (todos obrigatórios):
| Parâmetro | Valor |
|---|---|
response_type | code |
code_challenge_method | S256 |
client_id | Seu Client ID |
redirect_uri | Sua URI de loopback, por exemplo http://localhost:8765 (inclua a porta, sem barra final) |
scopes | Um por escopo, por exemplo scopes=read:basic&scopes=read:hierarchy |
code_challenge | O desafio PKCE gerado acima |
state | Seu valor de state aleatório |
Depois que o usuário fizer login e clicar em Allow, o navegador redireciona para sua URI de loopback:
http://localhost:8765/?code={authorization_code}&state={state}Se o usuário negar o acesso, você receberá ?error=access_denied em vez disso. Os códigos de autorização expiram após 60 segundos, portanto troque-os imediatamente.
Etapa 4: trocar o código por um token de acesso
Seção intitulada “Etapa 4: trocar o código por um token de acesso”Endpoint: POST https://cloud-api.prevu3d.com/oauth/token
Cabeçalhos: Content-Type: application/x-www-form-urlencoded
Corpo:
| Campo | Valor |
|---|---|
grant_type | authorization_code |
client_id | Seu Client ID |
code | Código do redirecionamento |
redirect_uri | A mesma URI usada na Etapa 3 (incluindo a porta) |
code_verifier | O verificador PKCE original |
Não envie um segredo de cliente para aplicativos nativos.
Exemplo de resposta:
{ "hasError": false, "expires_in": 86400, "access_token": "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9...", "refresh_token": "..."}Salve os dois tokens. Use o access_token para chamadas à API. Quando ele expirar, solicite um novo com grant_type=refresh_token e seu refresh_token armazenado (nenhum segredo de cliente necessário).
Etapa 5: obter a URL base da sua API
Seção intitulada “Etapa 5: obter a URL base da sua API”Chame o endpoint de descoberta para obter a apiUrl da sua organização. Não codifique uma URL regional de forma fixa.
Endpoint: GET https://cloud-api.prevu3d.com/oauth/api-info
Cabeçalhos: Authorization: Bearer <your_access_token>
Exemplo de resposta:
{ "user": { "..." : "..." }, "organization": { "id": "217ebd23-ec54-4af0-a6d6-4a441a6d1966", "name": "Test Organization" }, "scopes": ["read:basic", "read:hierarchy"], "apiUrl": "https://api-ue1.prevu3d.com/realityconnect-api"}Use o valor de apiUrl como base para todas as suas chamadas à API. Anote também o organization.id, de que você precisará em muitos endpoints.
Etapa 6: fazer sua primeira chamada à API
Seção intitulada “Etapa 6: fazer sua primeira chamada à API”Agora você tem tudo de que precisa: um token de acesso e sua URL base. Vamos fazer uma requisição simples para recuperar as divisões da sua organização:
GET {apiUrl}/v1/nodes/{organization_id}/browseAuthorization: Bearer <your_access_token>Exemplo com valores reais:
GET https://api-ue1.prevu3d.com/realityconnect-api/v1/nodes/217ebd23-ec54-4af0-a6d6-4a441a6d1966/browse HTTP/1.1Authorization: Bearer eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9...Uma resposta bem-sucedida contendo uma lista de divisões confirma que sua integração está funcionando corretamente.
Experimente com Python
Seção intitulada “Experimente com Python”Aqui está um script completo que faz tudo o que foi descrito acima. Substitua client_id pelo seu Client ID e execute-o. Ele inicia um servidor loopback temporário, abre a página de consentimento no navegador e imprime as divisões da sua organização assim que você aprovar.
import base64import hashlibimport jsonimport secretsimport webbrowserfrom http.server import BaseHTTPRequestHandler, HTTPServerfrom urllib.parse import parse_qs, quote, urlencode, urlparse
import requests
client_id = "your-client-id"base_url = "https://cloud-api.prevu3d.com"scopes = ["read:basic", "read:hierarchy"]
# Step 1: Authorize with PKCE and get an access tokenverifier = secrets.token_urlsafe(48)[:64]challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest()).decode().rstrip("=")state = secrets.token_urlsafe(32)auth_result = {"code": None, "state": None}
class Handler(BaseHTTPRequestHandler): def log_message(self, *args): pass
def do_GET(self): query = parse_qs(urlparse(self.path).query) auth_result["code"] = query.get("code", [None])[0] auth_result["state"] = query.get("state", [None])[0] self.send_response(200) self.end_headers()
server = HTTPServer(("localhost", 0), Handler)redirect_uri = f"http://localhost:{server.server_address[1]}"consent_params = urlencode( { "response_type": "code", "code_challenge_method": "S256", "client_id": client_id, "redirect_uri": redirect_uri, "code_challenge": challenge, "state": state, })consent_url = f"{base_url.replace('cloud-api.', 'cloud.', 1)}/oauth?{consent_params}"consent_url += "&" + "&".join(f"scopes={quote(scope)}" for scope in scopes)
webbrowser.open(consent_url)server.handle_request()
if auth_result["state"] != state: raise RuntimeError("Invalid state")if not auth_result["code"]: raise RuntimeError("Authorization failed")
token_response = requests.post( f"{base_url}/oauth/token", data={ "grant_type": "authorization_code", "client_id": client_id, "code": auth_result["code"], "redirect_uri": redirect_uri, "code_verifier": verifier, },)token_response.raise_for_status()access_token = token_response.json()["access_token"]
# Step 2: Get your API URL and org IDapi_info = requests.get( f"{base_url}/oauth/api-info", headers={"Authorization": f"Bearer {access_token}"},).json()
api_url = api_info["apiUrl"]organization_id = api_info["organization"]["id"]
# Step 3: Browse divisionsdivisions = requests.get( f"{api_url}/v1/nodes/{organization_id}/browse", headers={"Authorization": f"Bearer {access_token}"},).json()
print("Divisions:", json.dumps(divisions, indent=2))Solução de problemas
Seção intitulada “Solução de problemas”| Se você vir… | Tente isto… |
|---|---|
| Invalid OAuth grant request após clicar em Allow | Confirme que você está usando o Client ID de um aplicativo nativo (Authorization Code e Native app ativados). Um aplicativo somente Client Credentials não tem URI de redirecionamento e não consegue concluir esse fluxo. |
| Erro na página de consentimento sobre parâmetros de consulta | Garanta que response_type=code, code_challenge_method=S256 e todos os parâmetros obrigatórios estejam presentes, incluindo state e scopes. |
| 400 ou 403 na troca do token | O código pode ter expirado (limite de 60 segundos), a redirect_uri pode não corresponder à da Etapa 3, ou o verificador e o desafio PKCE podem não corresponder. |
| 403 Forbidden ao chamar a API | Uma requisição precisa passar pelas três camadas de segurança. Verifique os escopos OAuth, o acesso ao conteúdo do usuário conectado e a função do usuário no nó de destino. |
| Organização errada nas respostas da API | O usuário seleciona a organização na tela de consentimento. Autorize novamente e escolha a correta. |
Para problemas de conexão, DNS e URL da API, consulte Primeiros passos.
Próximos passos
Seção intitulada “Próximos passos”- Adicione lógica para renovar seu token antes de ele expirar usando
grant_type=refresh_tokencom seu refresh token armazenado. - Explore a referência da API para conhecer todas as operações disponíveis.