Autenticação
Um cabeçalho, um formato de token, e quatro recusas que respondem igual de propósito.
Uma integração carrega sua chave num cabeçalho, e nenhuma requisição dela é respondida sem ele.
Authorization: Bearer ulg_live_...O token
Um token é ulg_live_ seguido de 32 caracteres hexadecimais. O prefixo é o que
o torna reconhecível num log ou num texto colado, e é isso que torna possível
varrer por vazamentos.
Só um hash do token é guardado. Ninguém, nem nós, consegue ler uma chave depois de criada: a coluna que guarda o hash não é concedida a nenhum papel que fale com a API, então uma consulta que a alcance é recusada até para o próprio dono.
O que uma recusa significa
Chave desconhecida, revogada, expirada ou malformada respondem todas o mesmo:
401 invalid_key. Elas não são distinguidas de propósito, para que um token
não possa ser sondado até se descobrir de que jeito ele está errado.
Uma chave viva que não tem a permissão responde 403 insufficient_scope, e o
corpo nomeia o escopo que faltou:
{
"error": {
"code": "insufficient_scope",
"message": "This key does not hold library.write.",
"scope": "library.write"
}
}Até onde uma chave alcança
A requisição roda como a conta dona da chave. Uma chave com lists.write numa
conta que não pode escrever em certa lista privada continua não podendo,
porque quem recusa é a regra da própria lista, não o escopo.
Um escopo é um teto. Ele estreita o que a chave pode tentar; nunca amplia o que o dono dela pode fazer.
O site também entra por aqui
O uloggd não fala com o banco por fora da própria API: cada botão do site chama estas mesmas rotas. O que ele carrega é o cookie de sessão de quem está logado, e não uma chave, porque uma chave que o site criasse para si mesmo seria uma chave que ninguém poderia revogar.
Isso muda três coisas, e só três:
- Uma sessão não tem escopos. Ela é a própria conta, então
403 insufficient_scopenunca acontece com ela. - Uma sessão não gasta a cota de chave nenhuma, e a resposta não traz
X-RateLimit-*. Os limites que a conta já tinha continuam valendo. - Em
/api/v1/me,keyvemnull.
Um cookie só é aceito quando a requisição vem da própria origem, porque um cookie viaja sozinho e um cabeçalho não. Uma chave não passa por essa verificação: ela só chega se alguém a escreveu.
Quando o cabeçalho vem, é ele que decide. Uma chave revogada responde 401 invalid_key mesmo que o navegador também carregue uma sessão válida:
apresentar uma chave é dizer qual identidade se quer, e uma chave que continua
funcionando depois de revogada, enquanto quem a criou estiver logado, é uma
revogação que ninguém consegue testar.
Rotas só para sessão
Algumas rotas respondem só a uma sessão do próprio site, nunca a uma chave, porque uma chave não pode ganhar mais poder do que recebeu nem mexer na conta que a criou:
- tudo o que fica em
/api/v1/account: os aplicativos e as chaves, as sessões, o estado e a preparação da conta, a exportação, os dados, o nome de usuário, a data de nascimento, as identidades e as conexões, e toda rota de desenvolvedor e de jogador do Arcade, inclusive as da URL de desenvolvimento (GET,PUTeDELETE /api/v1/account/apps/{id}/arcade/override); - as imagens do layout do perfil (
/api/v1/profile/layout/media), que gastam o espaço da própria conta; - a denúncia de um jogo do Arcade (
POST /api/v1/reportscomonARCADE_APP).
Uma chave recebe 403 forbidden nelas. As do Arcade estão em
Recursos: Arcade. As da URL de
desenvolvimento também pedem uma sessão verificada com a verificação em duas
etapas, até para ler (veja
A URL de desenvolvimento).
Cuidando de uma chave
- Trate como senha, porque é uma que dispensa a senha.
- Dê uma chave para cada integração. Revogar uma não custa nada às outras.
- Revogue na aba Chaves do aplicativo, no portal, assim que uma chave escapar. A revogação vale já na requisição seguinte.