OAuth e apps de desenvolvedor
Registre e gerencie apps OAuth do Nodaro com client.developerApps, e troque códigos, revogue tokens e leia dados da tela de consentimento com client.oauth.
client.developerApps gerencia os apps OAuth que você possui: apps que permitem que outros usuários do Nodaro deem ao seu software acesso às contas deles. client.oauth cobre o lado do servidor do fluxo OAuth 2.0: troca um código de autorização por um token de acesso, revoga tokens e retorna os dados públicos que uma tela de consentimento mostra. O fluxo completo de consentimento está descrito em OAuth.
Métodos
| Método | O que faz |
|---|---|
developerApps.list() | Lista os seus apps |
developerApps.get(id) | Lê um app |
developerApps.create(input) | Registra um app e obtém o segredo dele |
developerApps.update(id, input) | Altera um app |
developerApps.delete(id) | Exclui um app |
developerApps.rotateSecret(id) | Substitui o segredo de um app |
oauth.exchangeCode(input) | Troca um código de autorização por um token de acesso |
oauth.revoke(token) | Revoga um token de acesso |
oauth.getAppInfo(clientId, redirectUri?) | Lê os dados públicos de um app para uma tela de consentimento |
Escopos
Um app pede escopos, e um usuário os aprova. O servidor aceita estes escopos:
| Escopo | Permite |
|---|---|
workflows:read | Ler workflows |
workflows:write | Criar e alterar workflows |
workflows:execute | Executar workflows |
jobs:read | Ler jobs |
assets:read | Ler personagens, locais, objetos e outras entidades |
assets:write | Criar e alterar entidades |
credits:read | Ler o saldo de créditos |
apps:read | Ler apps publicados |
pipelines:read | Ler pipelines |
pipelines:execute | Iniciar e cancelar pipelines |
pipelines:approve | Aprovar e rejeitar etapas de pipelines |
presets:read | Ler predefinições de nós |
workspaces:read | Listar os espaços de trabalho de que o usuário faz parte |
workspaces:write | Escolher o espaço de trabalho em que o app atua |
Apps OAuth mostra o que a tela de consentimento diz para cada escopo. Uma chamada sem o escopo de que precisa lança um ForbiddenError cujo missingScope indica qual é. Veja Escopos e permissões ausentes.
client.developerApps
Só o dono pode ler ou alterar um app. Os segredos são retornados exatamente uma vez.
developerApps.list()
Lista os seus apps.
list(): Promise<{ data: DeveloperApp[] }>const { data: apps } = await client.developerApps.list()
const mine = apps.filter((app) => (app.kind ?? "user") === "user")Um DeveloperApp tem id, name, description, logoUrl, homepageUrl, redirectUris, allowedOrigins, scopesRequested, clientId, status (active, suspended ou pending_review), kind, createdAt e updatedAt. kind é "user" para um app que você registrou. Os outros valores, dynamic_mcp, first_party_mcp e community_instance, são clientes que se registraram sozinhos. Só os apps "user" contam para o limite de cinco.
developerApps.get(id)
Lê um app. O segredo nunca vem incluído.
get(id: string): Promise<{ data: DeveloperApp }>Prop
Type
const { data: app } = await client.developerApps.get(appId)developerApps.create(input)
Registra um app. A resposta inclui clientSecret. Guarde-o agora: o servidor mantém apenas um hash dele.
create(input: CreateDeveloperAppInput): Promise<{ data: DeveloperApp & { clientSecret: string } }>Prop
Type
const { data } = await client.developerApps.create({
name: "My integration",
redirectUris: ["https://example.com/oauth/callback"],
scopesRequested: ["workflows:read", "workflows:execute"],
})
console.log(data.clientId, data.clientSecret) // save both nowVocê pode registrar cinco apps. Um sexto falha com 400 limit_reached.
developerApps.update(id, input)
Altera um app. Passe apenas os campos a alterar; as regras de create() valem para cada um.
update(id: string, input: UpdateDeveloperAppInput): Promise<{ data: DeveloperApp }>Prop
Type
await client.developerApps.update(appId, {
redirectUris: ["https://example.com/oauth/callback", "https://staging.example.com/oauth/callback"],
})developerApps.delete(id)
Exclui um app.
delete(id: string): Promise<{ success: true }>Prop
Type
await client.developerApps.delete(appId)Lança NotFoundError quando o ID não existe ou o app não é seu.
developerApps.rotateSecret(id)
Cria um novo segredo do cliente e invalida o antigo na hora. O novo segredo só é retornado uma vez.
rotateSecret(id: string): Promise<{ clientSecret: string }>Prop
Type
const { clientSecret } = await client.developerApps.rotateSecret(appId)Atualize o segredo no seu servidor imediatamente, porque as trocas de código com o segredo antigo deixam de funcionar.
client.oauth
Os endpoints OAuth 2.0 que o servidor do seu app chama. Os nomes dos campos usam snake_case, como no padrão OAuth.
oauth.exchangeCode(input)
Troca o código de autorização do redirecionamento de consentimento por um token de acesso (POST /v1/oauth/token). O SDK adiciona grant_type: "authorization_code" por você.
Nunca o chame de um navegador. A requisição contém o segredo do cliente, que deve ficar no seu servidor.
exchangeCode(input: {
client_id: string
client_secret: string
code: string
redirect_uri: string
}): Promise<{ access_token: string; token_type: "Bearer"; scope: string; expires_in: number }>Prop
Type
import { createClient, StaticTokenAuth } from "@nodaro/sdk"
const tokens = await client.oauth.exchangeCode({
client_id: process.env.NODARO_CLIENT_ID!,
client_secret: process.env.NODARO_CLIENT_SECRET!,
code: req.query.code as string,
redirect_uri: "https://example.com/oauth/callback",
})
// Act for the user who approved your app
const userClient = createClient({
baseUrl: "https://app.nodaro.ai",
auth: new StaticTokenAuth(tokens.access_token),
})scope lista os escopos concedidos, separados por espaços, e expires_in é a validade do token, em segundos.
oauth.revoke(token)
Revoga um token de acesso (POST /v1/oauth/revoke, RFC 7009). Sempre responde { success: true }, mesmo para um token desconhecido, porque o padrão proíbe revelar se um token era válido.
revoke(token: string): Promise<{ success: true }>Prop
Type
await client.oauth.revoke(accessToken)oauth.getAppInfo(clientId, redirectUri?)
Retorna os dados públicos de um app para uma tela de consentimento (GET /v1/oauth/app-info). Não precisa de token.
getAppInfo(clientId: string, redirectUri?: string): Promise<OAuthAppInfo>Prop
Type
const info = await client.oauth.getAppInfo(clientId, "https://yourapp.com/oauth/callback")
if (!info.redirectUriRegistered) throw new Error("Unregistered redirect URI")A resposta tem name, description, logoUrl, homepageUrl, scopesRequested e redirectUriRegistered. redirectUriRegistered é true apenas para uma URI registrada exatamente como foi passada, e null quando você não passa redirectUri. Isso permite que uma tela de consentimento recuse um redirecionamento não registrado sem revelar a lista de URIs.
Perguntas frequentes
Páginas relacionadas
Apps OAuth
Autenticação
Autenticação
Erros
Última atualização
Organizações e espaços de trabalho
Organizações e espaços de trabalho do Nodaro em TypeScript: crie escolas e equipes, convide membros, distribua códigos de entrada e veja o uso de créditos.
Tipos
Todos os tipos TypeScript, funções auxiliares e constantes que o @nodaro/sdk exporta, agrupados por recurso, com a página que documenta cada um.