API REST
A API do CloudHub tem oito operações. As bibliotecas cliente as encapsulam, mas qualquer cliente HTTP pode chamá-las diretamente; esta página documenta o formato das mensagens. A mesma API é descrita de forma interativa, em OpenAPI, em cloudhub.lacunasoftware.com/swagger.
Convenções
- URL base:
https://cloudhub.lacunasoftware.com. - Autenticação: toda operação exige a sua chave de API no header
X-Api-Key. Uma requisição sem ela, ou com uma chave desconhecida, recebe HTTP 401 com o corpo vazio. - JSON: os corpos de requisição e de resposta são JSON, com nomes de propriedade em camelCase.
- Valores binários (hashes, certificados, assinaturas) trafegam como strings base64. As operações
de certificado e de
sign-hashdevolvem uma string JSON pura, como"MIIH…". - Enumerações trafegam como strings, como
"SingleSignature"ou"CPF". Os valores numéricos que os clientes 1.x enviam (1paraSingleSignature) continuam aceitos. - Timeouts: a assinatura espera pelo provedor. Dê até dois minutos para o
sign-hash.
| Operação | Finalidade |
|---|---|
POST /api/sessions | Criar uma sessão em todos os provedores que têm um certificado para o signatário |
POST /api/sessions/services/{name} | Criar uma sessão em um único provedor |
GET /api/sessions/services | Descobrir provedores sem criar uma sessão |
GET /api/sessions/services/{name}/availability | Perguntar a um provedor se ele tem um certificado |
GET /api/sessions/certificate | Ler o certificado da sessão |
GET /api/v2/sessions/certificate | Ler o certificado da sessão, com o alias e o provedor |
POST /api/sessions/sign-hash | Assinar um hash com o certificado da sessão |
GET /api/sessions/custom-state | Ler de volta o customState informado na criação da sessão |
Sessões
POST /api/sessions
Cria uma sessão. Com um identificador, o CloudHub faz a descoberta e devolve só os provedores que têm um certificado para ele; sem identificador, devolve todos os provedores.
| Campo do corpo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
redirectUri | string | Sim | URI absoluta para onde o CloudHub devolve o usuário, com session acrescentado. Precisa estar cadastrada para a sua chave. |
identifier | string | Não | O CPF ou CNPJ do signatário, só com os dígitos. |
identifierType | CPF ou CNPJ | Não | Como interpretar identifier. Quando omitido, mais de 11 dígitos indica um CNPJ. |
type | tipo de sessão | Não | O que o usuário autoriza. O padrão é SingleSignature. |
lifetimeInSeconds | inteiro | Não | O tempo de vida da sessão a pedir ao provedor. O provedor pode conceder menos. |
customState | string | Não | Dados seus, guardados com a sessão e devolvidos por GET /api/sessions/custom-state. |
discover | booleano | Não | Se a descoberta deve ser feita. O padrão é true quando identifier é informado. false devolve todos os provedores e passa identifier a cada um como dica de login. true exige identifier. |
curl https://cloudhub.lacunasoftware.com/api/sessions \
-H "X-Api-Key: $CLOUDHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"identifier": "12345678909", "redirectUri": "https://app.example.com/sign/complete", "type": "SingleSignature"}'
A resposta é um SessionModel:
{
"services": [
{
"serviceInfo": {
"serviceName": "BirdID",
"provider": "SOLUTI",
"endpoint": "https://api.birdid.com.br/",
"badgeUrl": "https://cdn.lacunasoftware.com/img/psc/birdid.png"
},
"authUrl": "https://api.birdid.com.br/oauth/authorize?client_id=…"
}
]
}
Erros: InvalidRedirectUri, UnauthorizedRedirectUri, IdentifierRequiredToDiscover; HTTP 400
quando falta redirectUri.
POST /api/sessions/services/{name}
Cria uma sessão em um único provedor, sem descoberta. Use quando o usuário já escolheu o provedor.
name é um serviceName como o CloudHub o devolve, por exemplo BirdID.
O corpo aceita os mesmos campos de POST /api/sessions, exceto
identifierType. identifier, quando informado, é passado ao provedor como dica de login;
discover é ignorado.
A resposta é um único TrustServiceAuthParametersModel:
serviceInfo e authUrl.
Erros: ServiceNotFound (com details.name), InvalidRedirectUri, UnauthorizedRedirectUri.
Descoberta
GET /api/sessions/services
Faz a descoberta sem criar uma sessão e devolve os provedores que têm um certificado para o
identificador, como uma lista de TrustServiceInfoModel. Esta resposta
não tem authUrl.
| Parâmetro de query string | Obrigatório | Descrição |
|---|---|---|
identifier | Sim | O CPF ou CNPJ, só com os dígitos. |
identifierType | Não | CPF (padrão) ou CNPJ. |
curl "https://cloudhub.lacunasoftware.com/api/sessions/services?identifier=12345678909" \
-H "X-Api-Key: $CLOUDHUB_API_KEY"
Um provedor que não responde fica de fora da lista.
GET /api/sessions/services/{name}/availability
Pergunta a um provedor se ele tem um certificado para o identificador. Aceita os mesmos parâmetros
de query string de GET /api/sessions/services.
{
"discoveryAvailable": true,
"certificateFound": true
}
discoveryAvailable é false quando o provedor não conseguiu responder; nesse caso,
certificateFound é null.
Erros: ServiceNotFound (com details.name).
Usando uma sessão
Estas operações recebem o valor session que a sua URI de redirecionamento recebeu. Elas falham
com SessionInvalidOrAlreadyUsed quando o CloudHub não conhece a sessão ou o provedor não a aceita
mais. As operações de certificado e de sign-hash também falham com SessionExpired depois que o
tempo de vida da sessão acaba.
GET /api/sessions/certificate
Devolve o certificado da sessão, codificado em DER e depois em base64, como uma string JSON. Quando o provedor tem vários certificados para o usuário, o CloudHub escolhe o que está dentro da validade e foi emitido mais recentemente.
curl "https://cloudhub.lacunasoftware.com/api/sessions/certificate?session=9f2c…e81a" \
-H "X-Api-Key: $CLOUDHUB_API_KEY"
"MIIHGjCCBQKgAwIBAgI…"
GET /api/v2/sessions/certificate
Devolve o mesmo certificado como um CertificateModel, com o alias dele e o
nome do serviço do provedor:
{
"content": "MIIHGjCCBQKgAwIBAgI…",
"alias": "a5f1…",
"serviceName": "BirdID"
}
Passe o alias ao sign-hash como certificateAlias para assinar exatamente com esse certificado.
POST /api/sessions/sign-hash
Assina um hash com a chave do usuário e devolve o valor da assinatura, em base64, como uma string JSON.
| Campo do corpo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
session | string | Sim | O valor da sessão. |
hash | string | Sim | O hash a assinar, em base64. |
digestAlgorithmOid | string | Um dos dois | O OID do algoritmo de hash, como 2.16.840.1.101.3.4.2.1 para SHA-256. Tem precedência sobre digestAlgorithm. |
digestAlgorithm | string | Um dos dois | O nome do algoritmo, como SHA-256. |
certificateAlias | string | Não | O certificado com que assinar, vindo de GET /api/v2/sessions/certificate. O padrão é o certificado que GET /api/sessions/certificate devolve. |
curl https://cloudhub.lacunasoftware.com/api/sessions/sign-hash \
-H "X-Api-Key: $CLOUDHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"session": "9f2c…e81a", "hash": "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=", "digestAlgorithmOid": "2.16.840.1.101.3.4.2.1"}'
"Qy1kZ3N0b3JlIHNpZ25hdHVyZSB2YWx1ZS4uLg…"
Erros: DigestAlgorithmNameOrOidIsRequired, InvalidDigestAlgorithm, SessionExpired,
SessionInvalidOrAlreadyUsed.
GET /api/sessions/custom-state
Devolve o customState informado na criação da sessão, como uma string JSON, ou null quando não
houve nenhum. O parâmetro de query string session é obrigatório.
Erros: SessionInvalidOrAlreadyUsed.
Modelos
SessionModel
| Campo | Tipo | Descrição |
|---|---|---|
services | TrustServiceAuthParametersModel[] | Uma entrada por provedor. Vazia quando nenhum tem um certificado para o identificador. |
TrustServiceAuthParametersModel
| Campo | Tipo | Descrição |
|---|---|---|
serviceInfo | TrustServiceInfoModel | O provedor. |
authUrl | string | Para onde enviar o usuário para autorizar nesse provedor. |
TrustServiceInfoModel
| Campo | Tipo | Descrição |
|---|---|---|
serviceName | string | O nome do provedor no CloudHub, como BirdID. Vai no caminho das operações de um único provedor. |
provider | string | A empresa que opera o serviço, como SOLUTI. |
endpoint | string | O endereço da API do provedor. |
badgeUrl | string | O logotipo do provedor. Pode ser nulo. |
CertificateModel
| Campo | Tipo | Descrição |
|---|---|---|
content | string | O certificado, codificado em DER e depois em base64. |
alias | string | O identificador do certificado no provedor. |
serviceName | string | O provedor de onde o certificado veio. |
GetServiceAvailabilityResponse
| Campo | Tipo | Descrição |
|---|---|---|
discoveryAvailable | booleano | Se o provedor respondeu. |
certificateFound | booleano ou nulo | Se ele tem um certificado para o identificador. Nulo quando não respondeu. |
TrustServiceSessionTypes
SingleSignature, MultiSignature, SignatureSession, AuthenticationSession. Veja
Tipos de sessão.
IdentifierTypes
CPF, CNPJ.
Erros
| Status HTTP | Corpo | Significado |
|---|---|---|
| 400 | Um problema de validação, com os campos | Um campo obrigatório falta ou está malformado, como redirectUri. |
| 401 | Vazio | O header X-Api-Key falta ou a chave é desconhecida. |
| 422 | { "code", "message", "details" } | O CloudHub recusou a requisição. code é um dos códigos abaixo. |
| 500 | Uma string JSON com um código curto, como "4F1A2B" | Uma falha inesperada, muitas vezes no provedor. Informe o código ao suporte da Lacuna. |
{
"code": "UnauthorizedRedirectUri",
"message": "Unauthorized redirect URI",
"details": {
"redirectUri": "https://app.example.com/sign/complete"
}
}
| Código | Significado | O que fazer |
|---|---|---|
InvalidRedirectUri | redirectUri não é uma URI absoluta. | Envie a URI completa, com esquema e host. |
UnauthorizedRedirectUri | redirectUri não está cadastrada para a sua chave. details.redirectUri a mostra. | Peça ao suporte da Lacuna que a cadastre. Veja URIs de redirecionamento. |
IdentifierRequiredToDiscover | discover é true, mas não há identifier. | Envie o identificador ou retire discover. |
ServiceNotFound | Nenhum provedor tem esse nome. details.name o mostra. | Use um serviceName devolvido pelo CloudHub. |
DigestAlgorithmNameOrOidIsRequired | O sign-hash não tem digestAlgorithm nem digestAlgorithmOid. | Envie um dos dois. |
InvalidDigestAlgorithm | O nome ou o OID do algoritmo de hash não é reconhecido. | Envie o OID que a sua biblioteca de assinatura informa. |
SessionInvalidOrAlreadyUsed | O CloudHub não conhece a sessão, ou o provedor não a aceita mais, por exemplo porque ela já foi usada. | Crie uma nova sessão. |
SessionExpired | O tempo de vida da sessão acabou. Pode acontecer no primeiro uso, quando o usuário demorou a autorizar. | Crie uma nova sessão e envie o usuário ao provedor de novo. |