Emissão de token no backend
Troque a credencial da integração por acesso curto, mínimo e vinculado ao usuário do seu host.
Abrir como MarkdownA credencial nunca atravessa a fronteira
createReportPlatformClient é server-only. A troca usa autenticação Basic entre servidores e a rota de emissão não aceita CORS de navegador. Entregue ao cliente somente accessToken, tokenType e expiresIn.
import "server-only"
import { createReportPlatformClient } from "@rhizzalab/report-node"
import { NextResponse } from "next/server"
import { requireAuthenticatedUser } from "@/lib/auth"
export const runtime = "nodejs"
function requiredEnv(name: string): string {
const value = process.env[name]
if (!value) throw new Error("Variável ausente: " + name)
return value
}
const reports = createReportPlatformClient({
clientId: requiredEnv("RHIZZADOCS_CLIENT_ID"),
clientSecret: requiredEnv("RHIZZADOCS_CLIENT_SECRET"),
apiBaseUrl: process.env.RHIZZADOCS_API_URL,
})
export async function POST(request: Request) {
// Esta função pertence ao seu host: valide a sessão antes da troca.
const user = await requireAuthenticatedUser(request)
const token = await reports.issueEditorToken({
userId: user.id,
workspaceId: user.companyId,
reports: [
{
reportType: "acme.relatorio-mensal",
scopes: ["editor:read", "templates:read", "export:pdf"],
},
],
})
return NextResponse.json(token)
}Derive identidade e acesso no host
userId: id estável do usuário autenticado no seu sistema, entre 1 e 255 caracteres.workspaceId: contexto opcional do host, também entre 1 e 255 caracteres; não é autorização.reports: lista não vazia de paresreportType+scopes.scopes: somente capacidades que a tela realmente precisa naquele momento.
Renove sem refresh token
O token dura 10 minutos por padrão e nunca pode exceder 15 minutos. Quando o editor sinalizar AUTH_REQUIRED, chame novamente a sua rota autenticada e substitua o JWT em memória.
Se a sessão do próprio host expirou, não tente renovar em loop. Redirecione o usuário para o login do host e preserve a explicação de que a autenticação principal terminou.
Trate os erros do Node SDK
kind | Significado | Ação típica |
|---|---|---|
validation | Pedido inválido antes da rede | Corrigir o mapeamento do host |
api | API respondeu fora de 2xx | Usar status, code, requestId e issues |
network | Timeout, DNS, TLS ou fetch rejeitado | Aplicar retry limitado e observabilidade |
contract | Resposta 2xx fora do contrato | Interromper e investigar incompatibilidade |
import { isReportNodeError } from "@rhizzalab/report-node"
try {
return await reports.issueEditorToken(request)
} catch (error) {
if (isReportNodeError(error)) {
logger.warn({
kind: error.kind,
code: error.code,
status: error.status,
requestId: error.requestId,
})
}
throw error
}