Autenticação
Cada integrador recebe uma chave de API. Ela identifica um sistema, define quais estações ele enxerga e a qual cota ele está sujeito.
Envie a chave no cabeçalho X-Api-Key, em toda requisição:
curl https://api.radar-sandbox.kitelife.com.br/v1/stations \ -H "X-Api-Key: $RADAR_API_KEY"O cabeçalho Authorization: Bearer <chave> também é aceito e vale exatamente o
mesmo. Use o que for mais natural no seu cliente HTTP; muitos já trazem suporte
a Bearer embutido, e nesses casos não faz sentido montar um cabeçalho à mão.
Envie um ou outro, nunca os dois.
Chave ausente, inválida ou revogada devolve 401 com corpo
ProblemDetails e code: ApiKey.NotRecognized. Uma chave válida
pedindo uma estação fora do seu escopo devolve 404, não 403: do ponto de
vista da sua credencial, aquela estação não existe, e responder 403 revelaria
que ela existe para outra pessoa.
WebSocket
Seção intitulada “WebSocket”Depende de onde o cliente roda.
De servidor
Seção intitulada “De servidor”Qualquer cliente WebSocket de servidor controla os cabeçalhos do handshake, e aí
a autenticação é igual à da REST: mande Authorization: Bearer <chave> ou
X-Api-Key na abertura da conexão. Não é preciso mais nada.
// Node, biblioteca wsnew WebSocket('wss://stream.radar-sandbox.kitelife.com.br/v1/stream', { headers: { Authorization: `Bearer ${process.env.RADAR_API_KEY}` },})Do navegador
Seção intitulada “Do navegador”Do navegador não dá, e a limitação não é nossa: a API WebSocket do navegador
aceita apenas a URL e a lista de subprotocolos. Não existe forma de definir
Authorization nem qualquer outro cabeçalho no handshake.
Sobra colocar a credencial na URL, e uma URL vaza com facilidade: fica no
histórico, nos logs de qualquer proxy no caminho e no cabeçalho Referer. Por
isso o handshake do navegador usa um ticket:
- Peça um ticket na REST, autenticando com a chave normalmente.
- Abra a conexão com
wss://stream.radar-sandbox.kitelife.com.br/v1/stream?ticket=….
O ticket vale 60 segundos, serve para uma única conexão e herda o escopo
da chave que o emitiu. Peça um novo a cada reconexão: reaproveitar o anterior
falha com Ticket.Expired.
Vazado, um ticket vale quase nada. Vazada, uma chave vale tudo até ser revogada. É essa a diferença que o desenho compra.
Há quem passe o token pelo cabeçalho Sec-WebSocket-Protocol, que o navegador
deixa preencher. Nós não aceitamos esse caminho: ele resolve o transporte e
deixa o problema de fundo intacto, que é a chave de API estar dentro de um
navegador.
O relay usa usuário e senha AMQP próprios, entregues no provisionamento da sua fila, sobre TLS na porta 5671. As credenciais dão permissão de consumo apenas, na sua fila: você não declara filas, não altera bindings e não publica.
A chave de API da REST não vale no broker, e vice-versa. São credenciais separadas de propósito: vazar uma não compromete a outra.
Guardando a chave
Seção intitulada “Guardando a chave”A chave é uma credencial de servidor. Embutida em aplicativo móvel, em página web ou em repositório público, ela é uma chave pública: qualquer pessoa extrai. Se o seu front-end precisa dos dados, o caminho é seu servidor buscar e repassar.
Precisando de acesso direto do navegador, fale conosco antes. O desenho para esse caso é outro, com credencial de escopo reduzido, e não é a sua chave de integrador.
Rotação
Seção intitulada “Rotação”Uma chave comprometida deve ser trocada, e a troca não exige janela de indisponibilidade: emitimos a nova credencial deixando a antiga válida, você migra, e só então revogamos a antiga.
O mesmo vale para o AMQP, com um par adicional de usuário e senha.
Peça a rotação antes de trocar a configuração, nunca durante: revogar primeiro derruba a sua integração até a nova chave estar no ar.