breezeauth.com
PT
EntrarComece grátis
Usuários de serviçoTokens de acesso

Obter tokens de acesso

Troque a credencial de um usuário de serviço por um token de acesso no endpoint /oauth/token, use-o para chamar a API do BreezeAuth e solicite um novo quando ele expirar.

Nesta página
  1. Solicitar um token
  2. Chamar a API
  3. Quando o token expira: sem refresh tokens
  4. O que o BreezeAuth verifica
  5. Erros
  6. Exemplos de código
  7. Node.js
  8. Python

Um usuário de serviço não envia o seu client secret em cada chamada à API. Em vez disso, ele troca a sua credencial por um token de acesso: uma chave de curta duração que ele envia em cada requisição. Isso segue o fluxo client credentials do OAuth 2.0, a forma padrão de máquinas se autenticarem em APIs.

Esta página é técnica. Se você está configurando um usuário de serviço no console de administração, compartilhe-a com os desenvolvedores que vão construir a integração.

Solicitar um token

Envie uma requisição POST para o endpoint de token com o ID do cliente e o client secret da credencial:

curl -X POST https://api.breezeauth.com/oauth/token \
  -H 'Content-Type: application/json' \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "5f0c3a8e-2b7d-4e91-9a6c-1d2e3f4a5b6c",
    "client_secret": "<client secret>"
  }'
Campo Valor
grant_type Sempre client_credentials.
client_id O ID do cliente da credencial.
client_secret O Client secret da credencial, exibido quando ela foi criada.

Uma requisição bem-sucedida retorna 200 OK:

{
  "access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6Ij…",
  "token_type": "Bearer",
  "expires_in": 900
}
Campo Descrição
access_token O token a ser enviado nas requisições à API. Trate-o como confidencial, assim como o secret.
token_type Sempre Bearer.
expires_in Por quantos segundos, a partir de agora, o token é válido. Sempre leia esse valor da resposta; não o fixe no código.

Chamar a API

Envie o token no cabeçalho Authorization de cada requisição:

curl https://api.breezeauth.com/organizations/<organizationsUuid>/memberships \
  -H 'Authorization: Bearer <token de acesso>'

Substitua <organizationsUuid> pelo ID da sua organização, exibido abaixo do nome da organização na página Gerenciar Organização.

O que o usuário de serviço pode fazer depende do seu papel administrativo. Uma requisição fora desse papel é recusada com 401 Unauthorized.

Quando o token expira: sem refresh tokens

Os tokens de acesso têm curta duração de propósito: se um deles vazar, ele só será útil para um atacante por pouco tempo.

Quando um token expira, a integração simplesmente solicita um novo em /oauth/token com a mesma credencial. Por isso o BreezeAuth não emite refresh tokens para usuários de serviço, e a resposta não tem o campo refresh_token: um refresh token existe para que as pessoas não precisem entrar de novo, mas um usuário de serviço possui a sua credencial e sempre consegue obter um novo token sozinho.

Abordagem recomendada:

  • Reutilize um token enquanto ele for válido. Não solicite um novo token antes de cada chamada à API.
  • Solicite um novo token pouco antes de terminar o prazo de expires_in, ou quando uma chamada à API retornar 401 Unauthorized.
  • Se uma requisição continuar retornando 401 mesmo com um token novo, pare e avise alguém: provavelmente a credencial ou o usuário de serviço foi desativado.

O que o BreezeAuth verifica

Ao emitir um token, o BreezeAuth verifica se:

  • o client ID existe e o client secret confere;
  • a credencial está ativa e não passou da data em Expira em;
  • o usuário de serviço está Ativo;
  • a requisição vem de uma rede permitida, caso a organização tenha uma restrição de acesso por rede.

Em cada requisição à API, o BreezeAuth verifica novamente se:

  • o token é válido e não expirou;
  • a credencial que o emitiu continua ativa e não expirou, então desativar uma credencial corta os tokens dela imediatamente;
  • o usuário de serviço continua Ativo e o seu papel permite a operação;
  • a requisição vem de uma rede e de um país permitidos, caso a organização os restrinja.

Erros

Resposta Significado O que fazer
400 Bad Request em /oauth/token A requisição está malformada: falta um campo, o grant_type não é client_credentials ou o client_id não é um identificador válido. Corrija a requisição.
401 Unauthorized em /oauth/token A credencial não pode ser usada: client ID ou secret incorreto, credencial inativa ou expirada, ou usuário de serviço inativo. Por segurança, a resposta não diz qual é o motivo. Confira a credencial e o usuário de serviço no console de administração.
401 Unauthorized com network_not_authorized A requisição vem de uma rede fora das zonas de rede permitidas pela organização. Execute a integração a partir de uma rede permitida ou peça a um administrador para atualizar as zonas.
401 Unauthorized em uma chamada à API O token expirou, a credencial ou o usuário de serviço foi desativado, ou o papel do usuário de serviço não permite a operação. Solicite um novo token e tente uma vez mais. Se falhar de novo, confira a credencial, o usuário de serviço e o papel.
403 Forbidden com access_not_allowed_from_country A organização restringe o acesso por país, e a requisição vem de um país não permitido. Execute a integração a partir de um país permitido ou peça a um administrador para revisar a restrição.
429 Too Many Requests Requisições demais em pouco tempo. Reutilize os tokens em vez de solicitar um por chamada e diminua o ritmo.

Exemplos de código

Os exemplos abaixo solicitam um token, mantêm-no em memória, renovam-no antes de expirar e tentam uma vez mais quando a API retorna 401. Eles leem a credencial de variáveis de ambiente.

Node.js

Usa o fetch nativo (Node.js 18 ou superior).

const API_URL = 'https://api.breezeauth.com'

let cachedToken = null // { value, renewAt }

async function getAccessToken() {
  if (cachedToken && Date.now() < cachedToken.renewAt) {
    return cachedToken.value
  }

  const response = await fetch(`${API_URL}/oauth/token`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      grant_type: 'client_credentials',
      client_id: process.env.BREEZEAUTH_CLIENT_ID,
      client_secret: process.env.BREEZEAUTH_CLIENT_SECRET,
    }),
  })
  if (!response.ok) {
    throw new Error(`BreezeAuth token request failed with status ${response.status}`)
  }

  const { access_token, expires_in } = await response.json()
  // Renova quando 90% da validade tiver passado, para que o token nunca expire no meio de uma requisição.
  cachedToken = { value: access_token, renewAt: Date.now() + expires_in * 1000 * 0.9 }
  return cachedToken.value
}

export async function breezeAuthRequest(path, options = {}) {
  const send = async () =>
    fetch(`${API_URL}${path}`, {
      ...options,
      headers: { ...options.headers, Authorization: `Bearer ${await getAccessToken()}` },
    })

  let response = await send()
  if (response.status === 401) {
    // O token pode ter expirado ou sido invalidado: obtém um novo e tenta uma vez mais.
    cachedToken = null
    response = await send()
  }
  return response
}

// Exemplo: listar os usuários da organização.
// const response = await breezeAuthRequest(`/organizations/${organizationId}/memberships`)

Python

Usa requests.

import os
import time

import requests

API_URL = "https://api.breezeauth.com"

_cached_token = None  # (value, renew_at)


def get_access_token():
    global _cached_token
    if _cached_token and time.time() < _cached_token[1]:
        return _cached_token[0]

    response = requests.post(
        f"{API_URL}/oauth/token",
        json={
            "grant_type": "client_credentials",
            "client_id": os.environ["BREEZEAUTH_CLIENT_ID"],
            "client_secret": os.environ["BREEZEAUTH_CLIENT_SECRET"],
        },
        timeout=10,
    )
    response.raise_for_status()
    body = response.json()
    # Renova quando 90% da validade tiver passado, para que o token nunca expire no meio de uma requisição.
    _cached_token = (body["access_token"], time.time() + body["expires_in"] * 0.9)
    return _cached_token[0]


def breezeauth_request(method, path, headers=None, **kwargs):
    global _cached_token

    def send():
        all_headers = {**(headers or {}), "Authorization": f"Bearer {get_access_token()}"}
        return requests.request(method, f"{API_URL}{path}", headers=all_headers, timeout=30, **kwargs)

    response = send()
    if response.status_code == 401:
        # O token pode ter expirado ou sido invalidado: obtém um novo e tenta uma vez mais.
        _cached_token = None
        response = send()
    return response


# Exemplo: listar os usuários da organização.
# response = breezeauth_request("GET", f"/organizations/{organization_id}/memberships")

Última atualização: 13 de outubro de 2026