Autenticação

Na presente página irá ser descrito o processo de autenticação

O acesso à nossa API requer uma autenticação por OAuth 2.0 usando uma chave obtida directamente dentro da aplicação. Não são aceites, nem funcionarão, chaves de acesso obtidas na Google, já que essas são para aceder às APIs deles, Google, e não à nossa. Os passos a executar para aceder à nossa API são os seguintes:

Passo 1: Obtenção das credenciais de acesso à nossa API

Neste passo, deverão ser obtidos os seguintes dados, necessários para que possam aceder à nossa API:

  • Identificador (a que chamamos "OAUTH_CLIENT_ID", ou simplesmente "client_id", nos exemplos posteriores)

  • Segredo (a que chamamos "OAUTH_CLIENT_SECRET", ou simplesmente "secret", nos exemplos posteriores)

  • Endereço de autenticação por OAuth 2.0 (a que chamamos "OAUTH_URL" nos exemplos posteriores)

  • Endereço de acesso à API (a que chamamos "API_URL" nos exemplos posteriores)

Os três primeiros são requisitos para a autenticação (via OAuth 2.0) na API e o quarto é o endereço base de todos os pedidos feitos à API.

Os dados de acesso acima indicados são todos obtidos directamente da empresa à qual se pretende aceder via API. Para os obter, deverá fazer o seguinte:

  1. Entrar na empresa com uma conta de Empresário

  2. Aceder através do menu à opção Empresa > Configurações > Dados API

  3. Introduzir os dados do integrador, que irá receber os dados de acesso à API através de um link temporário, de 72h.

Passo 2: Autenticação no nosso serviço de OAuth 2.0 e obtenção do token de acesso à API

Antes de poder aceder à API, o utilizador deverá autenticar-se no nosso serviço de OAuth 2.0 e obter um token de acesso, chamado a partir de agora "access token", executando os passos seguintes:

Poderá ser feito um pedido GET ao endereço OAUTH_URL/token com:

Na query do URL, os parâmetros:

  • grant_type=client_credentials

Nos headers, os seguinte:

  • Content-Type: application/x-www-form-urlencoded

  • Authorization: o texto "Basic", seguido dum espaço, seguido dum texto formado pela concatenação do valor de "OAUTH_CLIENT_ID", seguido de ':', seguido do valor de "OAUTH_CLIENT_SECRET", tudo codificado em base 64. Por exemplo, se o valor de "OAUTH_CLIENT_ID" fosse "test" e o "OAUTH_CLIENT_SECRET" fosse "abcdef", o valor deste header seria "Basic dGVzdDphYmNkZWY=", sendo "dGVzdDphYmNkZWY=" o texto "test:abcdef" em base 64.

O exemplo seguinte ilustra como fazer o pedido, no terminal, usando cURL:

# GET
curl "${OAUTH_URL}/token?grant_type=client_credentials" \
     -H 'Content-Type: application/x-www-form-urlencoded' \
     -H 'Authorization: Basic dGVzdDphYmNkZWY='

Em alternativa, poderá ser feito um pedido POST ao endereço OAUTH_URL/token com:

Nos headers, os seguinte:

  • Content-Type: application/x-www-form-urlencoded

  • Authorization: o texto "Basic", seguido dum espaço, seguido dum texto formado pela concatenação do valor de "OAUTH_CLIENT_ID", seguido de ':', seguido do valor de "OAUTH_CLIENT_SECRET", tudo codificado em base 64. Por exemplo, se o valor de "OAUTH_CLIENT_ID" fosse "test" e o "OAUTH_CLIENT_SECRET" fosse "abcdef", o valor deste header seria "Basic dGVzdDphYmNkZWY=", sendo "dGVzdDphYmNkZWY=" o texto "test:abcdef" em base 64.

No body do pedido, uma query "URL-encoded" com os parâmetros:

  • grant_type=client_credentials

O exemplo seguinte ilustra como fazer o pedido, no terminal, usando cURL:

# POST
curl -X 'POST' "${OAUTH_URL}/token" \
     -H 'Content-Type: application/x-www-form-urlencoded' \
     -H 'Authorization: Basic dGVzdDphYmNkZWY=' \
     --data-urlencode "grant_type=client_credentials"

A resposta esperada é como a seguinte:

{"access_token":"A-BBBBBBBB-CCCCCCCC-DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD", "refresh_token":"A-BBBBBBBB-CCCCCCCC-EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE","expires_in":14400,"token_type":"Bearer"}

O exemplo seguinte ilustra o pedido feito no terminal, usando o cURL:

> POST /oauth/token HTTP/1.1
> Content-Type: application/x-www-form-urlencoded
> Authorization: Basic dGVzdDphYmNkZWY=
> Content-Length: 29
> 
< HTTP/1.1 200 OK
< Content-Type: application/json;charset=utf-8
< Content-Length: 232
<
< {"access_token":"A-BBBBBBBB-CCCCCCCC-DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD", "expires_in":14400 "refresh_token":"A-BBBBBBBB-CCCCCCCC-EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE", "token_type":"Bearer"}

Ou seja, a resposta esperada é um status 200 (OK) e um JSON no qual se encontra o parâmetro "access_token" e o "refresh_token". O "access_token" e o "refresh_token" deverão ser guardados para uso posterior. O "access_token" terá que ser enviado (ver passo 3) em TODOS os pedidos de acesso à API, tendo a validade definida no parâmetro "expires_in" (em s) da resposta anterior. Após este tempo, os pedidos à API começarão a devolver um erro 401 (Unauthorized), e terá que ser pedido um novo "access_token" (repetindo o passo 2) ou renovado o existente usando o "refresh_token" (executando o passo 2.1).

Passo 2.1: Actualização do token de acesso usando o código de actualização

Este passo é necessário quando o token de acesso à API ("access_token") expira, mas pode ser utilizado em qualquer momento, por exemplo, para evitar que aconteça a expiração.

Usando o código de actualização ("refresh_token") obtido em 2 deverá ser feito um pedido POST ao endereço OAUTH_URL/token com:

No body do pedido, uma query "URL-encoded" com os parâmetros:

  • grant_type=refresh_token

  • refresh_token= o "refresh_token" obtido do passo anterior, que deve ser guardado para esse efeito.

Nos headers, o seguinte:

  • Content-Type: application/x-www-form-urlencoded

  • Authorization: o texto "Basic", seguido dum espaço, seguido dum texto formado pela concatenação do valor de "OAUTH_CLIENT_ID", seguido de ':', seguido do valor de "OAUTH_CLIENT_SECRET", tudo codificado em base 64. Por exemplo, se o valor de "OAUTH_CLIENT_ID" fosse "test" e o "OAUTH_CLIENT_SECRET" fosse "abcdef", o valor deste header seria "Basic dGVzdDphYmNkZWY=", sendo "dGVzdDphYmNkZWY=" o texto "test:abcdef" em base 64.

O exemplo seguinte ilustra como fazer o pedido, no terminal, usando cURL:

curl -v -X POST \
-H 'Content-Type: application/x-www-form-urlencoded' \ 
-H 'Authorization: Basic dGVzdDphYmNkZWY=' \
-d 'grant_type=refresh_token&refresh_token=<refresh_token>' \
"${OAUTH_URL}/token"

A resposta esperada é como a seguinte:

> POST /oauth/token HTTP/1.1
> Content-Type: application/x-www-form-urlencoded
> Authorization: Basic dGVzdDphYmNkZWY=
> Content-Length: 29
> 
< HTTP/1.1 200 OK
< Content-Type: application/json;charset=utf-8
< Content-Length: 232
<
< {"access_token":"A-BBBBBBBB-CCCCCCCC-DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD", "expires_in":14400 "refresh_token":"A-BBBBBBBB-CCCCCCCC-EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE", "token_type":"Bearer"}

Ou seja, a resposta esperada é um status 200 (OK) e um JSON no qual se encontra o (novo) parâmetro "access_token" e o (novo) "refresh_token". O novo "access_token" e o novo "refresh_token", tal como no passo 2, deverão ser guardados para uso posterior. Outro metodo de autenticação OAuth 2.0 ( Authorization Code flow ) encontra-se disponível em aqui.

Passo 2.2: Selecção do exercício fiscal

A lista de exercícios fiscais da empresa disponíveis, incluindo se o utilizador da API tem permissões de leitura e escrita, pode ser obtida da seguinte forma:

get
Responses
200
OK
application/json
get
GET /fiscal_years_list HTTP/1.1
Host: <API_URL>
Accept: */*
200

OK

{
  "data": []
}

A definição do exercício de trabalho que deverá ser usado pela API, é efetuada através de um pedido PUT para com o recurso "entity_sub_switch":

put
Body

Configuração de um exercício fiscal como sub-entidade na sessão

actionstringRequired

Valor fixo: sub-switch

Example: sub-switch
to_subtypestringRequired

Valor fixo: fiscal-year

Example: fiscal-year
to_subentity_idstringRequired

Identificador de sub-entidade, neste caso o exercício fiscal pretendido

Example: pt999999990_1#y2024_1_
Responses
200
OK
application/json
put
PUT /entity_sub_switch HTTP/1.1
Host: <API_URL>
Content-Type: application/json
Accept: */*
Content-Length: 93

{
  "action": "sub-switch",
  "to_subtype": "fiscal-year",
  "to_subentity_id": "pt999999990_1#y2024_1_"
}
200

OK

{
  "access_token": "1-123-456-123abc456def789ghi",
  "access_ttl": 86400
}

A resposta esperada é um status 200 (OK) e um JSON no qual se encontra o (novo) parâmetro "access_token". O "access_token" devolvido na resposta deverá ser utilizados nos pedidos seguintes.

Passo 3: Acesso autenticado à API comercial

Todos os pedidos à API, cujos endereços são os documentados em https://cloudware.gitbook.io/documentacao-api, são feitos para o endereço "API_URL" seguido do nome do recurso, usando o "access_token" obtido conforme descrito em 2.2 ou 2.4.

Além disso, todos os pedidos deverão conter obrigatoriamente os seguintes headers:

  • Content-Type: application/vnd.api+json

  • Accept: application/json

  • Authorization: o texto "Bearer", seguido dum espaço, seguido do "access_token" obtido anteriormente

Os parâmetros adicionais a passar na query (no caso de GET) ou no body dos pedidos são os especificados pelo padrão JSONAPI, a que a nossa API obedece, e que estão documentados em jsonapi.org.

Como exemplo, indica-se um pedido GET ao recurso "commercial_sales_documents" (documentos de venda), paginado para devolver apenas os 5 primeiros registos.

curl -v -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/json'\ 
-H 'Authorization: Bearer <access_token>' \
'<API_URL>/commercial_sales_documents?page[size]=5'

A resposta esperada, neste caso, é como a seguinte:

GET /commercial_sales_documents?page[size]=5 HTTP/1.1 
Content-Type: application/vnd.api+json 
Accept: application/json 
Authorization: Bearer  <access_token> 
HTTP/1.1 200 OK 
Content-Type: application/vnd.api+json;charset=utf-8 
{"data":[{"type":"commercial_sales_documents","id":"...","attributes":{...}}, ...]}

Ou seja, e se não ocorrer nenhum erro (como o tentar uma consulta a algo que não existe, ou criar um registo com valores incorrectos), a resposta esperada é um status 200 (OK) e um JSON, no formato JSONAPI, contendo o registo ou os registos devolvidos (no caso dos GET), criados (POST) ou alterados (PATCH). Como se disse no passo 2.2, se o pedido devolver um status 401 (Unauthorized), provavelmente o "access_token" já expirou, e terá que ser actualizado, ou pedido um novo efectuando novamente o passo 2.3.

Last updated