Versões comparadas
Chave
- Esta linha foi adicionada.
- Esta linha foi removida.
- A formatação mudou.
CONTEÚDO
Informações | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
01.
VISÃO GERALDisponibilizar um modelo de autenticação e autorização de acesso a recursos (endpoints), que permita abstração e flexibilidade com a utilização de um serviço de login independente (conforme modelo de arquitetura especificado na RFC000010 e RFC000015).
02. CONCEITOS APLICADOS
OAuth2 é um protocolo que permite aos usuários ter acesso a determinados recursos sem precisar expor suas credenciais. Por isso, serão usados os fluxos de autenticação e autorização baseados no OAuth2.
COMO FUNCIONA
Ao entrar em uma empresa com controle de acesso, é necessário efetuar previamente o cadastro na portaria (autenticação).
De acordo com a sua visita, a portaria garantirá a autorização de acesso temporária e você receberá um crachá para entrar em determinadas portas.
Independente da restrição que o crachá impõe a seus utilizadores, a ideia é clara: você dá a alguém acesso limitado as portas de acordo com a sua visita.
PARA QUE SERVE
Análogo ao crachá, para obter acesso limitado a recursos usando o OAuth2, utiliza-se um access token (token JWT), que permite usufruir recursos de terceiros de forma segura.
TIPOS DE CONCESSÃO DE ACESSO
A TOTVS utilizará no novo serviço de login um dos fluxos propostos pelo framework Oauth2, abaixo a sua especificidade:
- O Grant Type para autenticação (Client Credentials ou Resource Owner Password Credentials);
- Autorização de acesso conforme validade do token de acesso informado.
TIPOS DE GARANTIA DE ACESSO
Para o ERP ficar dentro da especificação e ter o escopo adequado, a TOTVS seguirá a implementação de dois tipos de Grant:
Visão Geral
Apresentar o modelo de autenticação Client Credentials e sua autorização de acesso aos endpoints.
Este modelo deve ser utilizado quando:
- O endpoint é acessado entre serviços "Machine to Machine (M2M)", que não necessitam de dados do usuário do ERP Datasul.
02. Conceitos Aplicados
Client Credentials
Esse tópico aborda a autorização entre serviços (M2M) onde o Client age em seu próprio nome Resource Server.Server
Image Modified
Modelo de acesso
comcom Client Credentials
Abaixo estão listados os componentes do desenho acima:
IDM: Solução que garante a autenticidade do Resource Owner
Oauth Provider: Solução que assume o papel de Oauth Provider e atua como Authorization Server, esse componente tem a responsabilidade de assinar o access_token com chave assimétrica. O Authorization Server consome uma fila de propagação "Role x ClientId" produzida pelo componente RBAC que persisti para possibilitar a geração do access_token auto-contido com as "Roles" do ClientId. O Authorization Server deve verificar a base para invalidação do clientId de modo que o mesmo ao tentar renovar o access_token utilizando seu refresh_token ou autorizar seja invalidado pelo Oauth Provider;
RBAC: Esse componente é responsável por gerir as permissões possibilitando termos uma relação de "Role x Grant". A responsabilidade de verificação desse componente é classificada como extremamente crítica. A solução permite que o RBAC tenha consistência eventual delegando a verificação de "Grant x ClientID" para uma camada na aplicação (Resource Server);
Resource Server (APP 2): A aplicação que hospeda o recurso tem a responsabilidade de enviar suas Grants para o RBAC via fila. Esse componente também deve consumir a fila de propagação de "Role x Grant" e gravar os dados recebidos para possibilitar a verificação de permissão das "Roles" que estarão auto-contidas no access_token. O Resource Server tem posse da chave pública para a verificação do access_token. Percebe-se que é necessário a construção de uma abstração para as aplicações;
Client (APP 1): O Client é o consumidor do recurso e assume o papel de Resource Owner quando o "grant_type" é client_credentials, com isso, o Client precisa das credenciais client_id e client_secret gerados no momento do registro no Oauth Provider. Assumindo que o Client é o próprio Resource Owner não há a necessidade de delegação de acesso.
A proposta aborda a autorização entre usuário Resource Owner e Client. Nesse caso o Client assume o papel de Resource Server, com isso, ele hospeda os recursos.
Image Removed
Figura 2 - Modelo de acesso com Resource Owner Password Credentials
Abaixo estão listados os componentes do desenho acima:
Oauth Provider: O mesmo do modelo anterior;
DAC: Esse componente é responsável por gerir as permissões a nível "granular" possibilitando que um usuário possa conceder a permissão para outro usuário;
Resource Server (APP 2): O mesmo do modelo anterior
- Nesse caso o Resource Server também é o Client. O Client gerencia o access_token e o Resource Server faz a verificação com a chave pública;
Resource Owner: Nesse Grant Type o usuário é o responsável pelas ações no Resource Server, logo o mesmo pede uma autorização em seu nome;
- A requisição de autorização é denominada
grant_type=password
onde o usuário passa suas credenciais para um Client do tipo confidencial. O Client por sua vez deve pedir uma autorização ao Oauth Provider e obter o access_token.
- A requisição de autorização é denominada
03. EXEMPLO DE UTILIZAÇÃO
03. Exemplos de Utilização
Autenticação
Nota | ||
---|---|---|
| ||
Gerar as credenciais de acesso conforme documentação: CFG - OAuth2 Caso seja necessário restringir o acesso com base na URL do endpoint, o escopo deve ser parametrizado na tela das credenciais de acesso. |
Como exemplo, foi efetuado um cadastro para o acesso aos endpoints que pertencem ao /btb:
Image Added
A autenticação conforme credenciais de acesso geradas na tela de Configurações
a. Otimização das Libs do Datasul
Para efetuar melhorias contínuas na manutenção, inovações, expedição do produto e otimização na utilização de memória do servidor Web (Tomcat), são utilizados conceitos de lib centralizadas.
Spike de validação do conceito de lib centralizada
b. Configuração baseada no OAuth2
As configurações para utilização dos conceitos de login conforme OAuth2 são realizadas nas telas de Propriedades, disponíveis no produto.
c. Client Credentials - Autenticação
A autenticação é necessária para obter o token JWT, para isto foi desenvolvido um endpoint que retorna dados para futuras utilizações:
Método: POST
URL: http://{{host}}:{{port}}/totvs-login-oauth2/oauth2/token?grant_type=client_credentials
Authorization: Basic Auth (Obrigatório)
- Informar as credenciais Id cliente, Senha cliente parametrizadas em Propriedades → OAuth2
Aviso | ||
---|---|---|
| ||
O endpoint de autenticação permite o envio das credenciais por parâmetros, porém segundo a RFC6749 esta forma de envio não é recomendada e deve ser limitada somente a clientes incapazes de utilizar o esquema de autenticação HTTP Basic. https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1 Caso seja realmente necessário o envio por parâmetros, os mesmos só podem ser transmitidos no corpo da solicitação com o tipo: Content-Type: application/x-www-form-urlencoded |
Image Removed
Caso a autenticação seja realizada com sucesso, é retornado o token com o formato abaixo:
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{
"access_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIwMjAwMTBzOGgyZ2ZpOTBoQ1duUG9WQXhnOERnNTUiLCJpYXQiOjE2NTY1MjM5MzYsImV4cCI6MTY1NjUyNDA1NiwiYXVkIjoiand0LmlvLmFwYWNoZS5leHRlcm5vIiwic2NvcGUiOlsiL2J0YiJdfQ.ZEMaRafOnFyUDkN198y5g2OkJuKfoS_zLDCXvP98XJ7hR--WTXnaQlEvTLmYf_Zhs6qmZHzpslE1hYRzzJRqPkRcuJ1LY_rAjiQJ8Zgk_NnHfT5HaAS0ut8G6rtJYIS9W_6FAAqal5PZE_iNwUd5mlVUT7_9SpNlSzhb3eH0r2Fe-Wceb6pJIrCI0UA_9UCAwvbQrDadcJXJGWjSqgf2l_B3K1HossFnCnAXsVCXsqVxofld4n9wnFD8B_qhy9UNSxbEayUjpOrJYmq4v5WvVFBG2XMk516ojFR3bT-q2PV-sWOqr8XyV-Qb7-cvkGNes9_DHKKkmUo3B77DP--Bjg",
"token_type": "Bearer",
"expires_in": 120,
"scope": "/btb"
} |
Nota | ||
---|---|---|
| ||
Neste conceito não ocorre a revogação do token JWT (logout / invalidate), o controle é realizado de acordo com o tempo de expiração do próprio token que pode ser parametrizado na tela de Propriedades → JWT. |
d. Client Credentials - Autorização
De posse com o token JWT gerado na etapa anterior, para acessar determinados recursos / endpoint, bastaria enviar o token na requisição com o formato Bearer Token:
Exemplo...
Método: GETURL: http://{{host}}:{{port}}/api/btb/v1/properties/general
Authorization: Bearer (Informar o token JWT)
Dica | ||
---|---|---|
| ||
Nesta etapa são realizados diversas validações de autorização ao recurso / endpoint, tais como a integridade do Token JWT, validade, escopo e audiência, onde todas as informações necessárias já estariam presentes no próprio token. Possíveis status de retorno:
|
e. Resource Owner Password Credentials - Autenticação
Para utilizar o modelo de autenticação com o Resource Owner Password Credentials, foi desenvolvido um endpoint que retorna dados para futuras utilizações:
Image Removed
Método: POST
URL: http://{{host}}:{{port}}/totvs-login-oauth2/oauth2/token?grant_type=password
Authorization: Basic Auth
Método de autenticação EMS: Informar o usuário e senha do produto (usuário tipo Interno)
Método de autenticação LDAP: Informar o usuário (dominio\usuário) e senha de rede (usuário do tipo Externo)
Aviso | ||
---|---|---|
| ||
O endpoint de autenticação permite o envio das credenciais por parâmetros, porém segundo a RFC6749 esta forma de envio não é recomendada e deve ser limitada somente a clientes incapazes de utilizar o esquema de autenticação HTTP Basic. https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1 Caso seja realmente necessário o envio por parâmetros, os mesmos só podem ser transmitidos no corpo da solicitação com o tipo: Content-Type: application/x-www-form-urlencoded |
Body:
- companyId (Opcional): Enviar como x-www-form-urlencoded, o código da empresa para direcionar a conexão. o broker que conecta com o PASOE
Image Added
Caso a autenticação seja realizada com sucesso, é retornado o token com o formato abaixo:
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{ "access_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJzdXBlciIsImlhdCI6MTY1NjUyOTkzNCwiZXhwIjoxNjU2NTMwMDU0LCJhdWQiOiJqd3QuaW8uYXBhY2hlLmV4dGVybm8iLCJ0ZW5hbnRJZCI6ImY3N2Q4ZjM2LTQzYzYtOWJiMS05NzE0LWQyMTBhOGI1MzcwYSIsInNjb3BlIjpbIioiXX0eyJzdWIiOiIwMjAwMTB3cmFBeEw0dmhhVFpncjJrTmVSOXRnNjYiLCJpYXQiOjE3MzM5MjU3OTIsImlzc3VlciI6ImRhdGFzdWwiLCJpc3MiOiJkYXRhc3VsIiwianRpIjoiNGEyZDA4NTItMjlkMi00NjYwLWFjZjEtNDVmODIyYTg0NzgyIiwiZXhwIjoxNzMzOTI3NTkyLCJhdWQiOiJsb2NhbGhvc3QuODA4MCIsInNjb3BlIjpbIi9idGIiXX0.b43eHEraKQh63ekGGKbR6V_xjGZqkSIC6h1m7ZamFxb1jcAKCDjyWvOh7VjWE5QZkwnozTtAudQSGE3CaThvhiKeOMBPADeaRiXY1G6u48aKdnYiD6RHNBH0kBkRsNH8P3Oyh-R8A1xofERqhymnPKXhtctCITCB-me1OnTbcMoRwFMSd76w1AF9mT9U262X8noZcqyQ89S0sCGzbsRrqXH5AOkcUAdrBITBMMevH-wmav93w-CnFpCekUHjJm1non055SGUCtRX5XyWTNCl2KHCN6Wx6i3q7JEmoT_-MABp2PV48qtom03hyj5UkqhkdHgGJVij7yUJdQS2QiQAQKrsnRrfEaBY2kpMt4hYPwjPbUIVw3ZYhDX9ZKz56y_VB3MoteuxThxyhNZq7PoMHs4YrqMMubddPFrRm5Xgl4eCdTzC_XvfXw8zo2hWEAl0zGBPTQXgGdjsJwIaQcOu5GOe5zBW0zQfSIOkkNiJLgIg", "token_type": "Bearer", "expires_in": 120, "scope": "*" } |
Params:
- scope (Opcional): Há a possibilidade de enviar o parâmetro scope para receber o token com este parâmetro. Caso não for enviado, o resultado do scope sempre será "*".
Caso exista mais de um valor dentro de scope, deverá ser enviado com uma separação por vírgula, conforme abaixo:
Image Removed
Caso enviado, é retornado o token conforme exemplo abaixo:
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{ "access_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJjMjAzZjY2OS0yMTIzLTgyYWYtNDExNC05MDg5NzAxYTUxMTAiLCJpYXQiOjE3MTI2OTM4NjQsImlzc3VlciI6ImRhdGFzdWwiLCJpc3MiOiJkYXRhc3VsIiwianRpIjoiNmJmYzI2N2QtOWJjYS00ZjkxLWE0YzYtMWJlZmVmYjc5ZDYzIiwiZXhwIjoxNzEyNzAzODYzLCJhdWQiOiJKVk4wNjAxMDU2MzE6ODA4NiIsImNvbXBhbnlJZCI6ImEzNTQwYzliLTJjZTMtODE5OS1iMzE0LWJkMDE4MDc2MDhmMyIsInNjb3BlIjpbIi9hcGkiLCIvYXBpL2R0cyIsIi90b3R2cy1sb2dpbiJdfQ.MHmnHNBL3VGrJXBRsf1ip6m74QK6eVfpCX5_jgO8Zp1wbrS_MKQms3n0KQdx-AGJToDwOWC5kMFIqWy8Wkog_N_PBdf603zeg_NmqCyj9JSNw_SLFuqOClLXQdUwIVUr-hf5jslcPKbZxyn_Xfb1RgbIR-wh_2xABdoIduWqohPjzRSB3O5WCdtHmURIMakGYeKqIT1F7LOGAvF2xUdT8ODDsu0MzjTjexz1dwO95YCnWsgcpbGrXXc8l_pETQbCF7S3C5nPsscoNRmd8PjMo9tIjyiEbuR8Pi-xHWZF8hOMbjuexm3_rl2CLRTWAwJurOmINwc2ooRqK3Cjp8v0sQxNQA5c0nefIUCLrqzOCkTbaEs40BAl9iMR3EWcJL6x68N0jdxekuIHlP9vfOqs-I4UxBCGHWZxgp7lK-BRTeviXgiQRnEfIJSVtG9lAZI7pU_O9M1Cinp_4ZIZXLdXbcr3y1Q7PeiFSkRx7LXrYeRMDFDinBNa6vRwCRUnHOebTnibfhUR_m0uET6YA", "token_type": "Bearer", "expires_in": 1201800, "refresh_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJjMjAzZjY2OS0yMTIzLTgyYWYtNDExNC05MDg5NzAxYTUxMTAiLCJpYXQiOjE3MTI2OTM4NjUsImlzc3VlciI6ImRhdGFzdWwiLCJqdGkiOiI5ZjZkMjZkNS0wZjliLTQ0YmMtYmViZC01MGE5ZDBlYTg3ZDYiLCJhY2Nlc3NUb2tlbiI6IjZiZmMyNjdkLTliY2EtNGY5MS1hNGM2LTFiZWZlZmI3OWQ2MyIsImV4cCI6MTcxMjcwMzg2NH0eyJzdWIiOiIwMjAwMTB3cmFBeEw0dmhhVFpncjJrTmVSOXRnNjYiLCJpYXQiOjE3MzM5MjU3OTIsImlzc3VlciI6ImRhdGFzdWwiLCJpc3MiOiJkYXRhc3VsIiwianRpIjoiNTQ2NzQ3NTgtYTY3Ny00N2Q2LWI0OWEtOWRjY2I0OWM2ZGIzIiwiYWNjZXNzVG9rZW4iOiI0YTJkMDg1Mi0yOWQyLTQ2NjAtYWNmMS00NWY4MjJhODQ3ODIiLCJleHAiOjE3MzM5Mjc1OTJ9.fg8hgwZfZdqlCsCTDVCNxqwRkVBlHqohkCa7bQphH60ntC-R_TVj9qFLNnIUvj8yKh9NH0o1aYDXmyHAMr-MjuUU5Fj7XC3IlmCuKXGT46_5zsydQfWUsjfn9ngkip8Vf70pz6utwANFd-MUqOla1toDETtxPQ0nLbHhL_sqx-scfM6-vcz4VufCgAwabR6bTUn7oL0LMv4twNeKHUpXcHjcjjfpMik4E1o_Cbw0lbtqtAyM52uih_OttrIolZAHgmQLubukJa7WHZsehU0kLiaqZsIfgOM7v2F5nTz5AfbbwrlRp4loWcoVSD2B5GdNzlZwhgdRQUq17RZvpR3Ew-8f4MXwlxWglR7MQZGylZAsbLt-rfBs8_nBbakRbX4rPLQ", "scope": "/api /api/dts /totvs-login" } |
Caso o parâmetro scope não for enviado, é retornado o token conforme exemplo abaixo, com o valor de scope igual a "*":
Bloco de código | ||||||
---|---|---|---|---|---|---|
| ||||||
{ "access_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJjMjAzZjY2OS0yMTIzLTgyYWYtNDExNC05MDg5NzAxYTUxMTAiLCJpYXQiOjE3MTI2OTM4NjQsImlzc3VlciI6ImRhdGFzdWwiLCJpc3MiOiJkYXRhc3VsIiwianRpIjoiNmJmYzI2N2QtOWJjYS00ZjkxLWE0YzYtMWJlZmVmYjc5ZDYzIiwiZXhwIjoxNzEyNzAzODYzLCJhdWQiOiJKVk4wNjAxMDU2MzE6ODA4NiIsImNvbXBhbnlJZCI6ImEzNTQwYzliLTJjZTMtODE5OS1iMzE0LWJkMDE4MDc2MDhmMyIsInNjb3BlIjpbIi9hcGkiLCIvYXBpL2R0cyIsIi90b3R2cy1sb2dpbiJdfQ.MHmnHNBL3VGrJXBRsf1ip6m74QK6eVfpCX5_jgO8Zp1wbrS_MKQms3n0KQdx-AGJToDwOWC5kMFIqWy8Wkog_N_PBdf603zeg_NmqCyj9JSNw_SLFuqOClLXQdUwIVUr-hf5jslcPKbZxyn_Xfb1RgbIR-wh_2xABdoIduWqohPjzRSB3O5WCdtHmURIMakGYeKqIT1F7LOGAvF2xUdT8ODDsu0MzjTjexz1dwO95YCnWsgcpbGrXXc8l_pETQbCF7S3C5nPsscoNRmd8PjMo9tIjyiEbuR8Pi-xHWZF8hOMbjuexm3_rl2CLRTWAwJurOmINwc2ooRqK3Cjp8v0sQ", "token_type": "Bearer", "expires_in": 120, "refresh_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJjMjAzZjY2OS0yMTIzLTgyYWYtNDExNC05MDg5NzAxYTUxMTAiLCJpYXQiOjE3MTI2OTM4NjUsImlzc3VlciI6ImRhdGFzdWwiLCJqdGkiOiI5ZjZkMjZkNS0wZjliLTQ0YmMtYmViZC01MGE5ZDBlYTg3ZDYiLCJhY2Nlc3NUb2tlbiI6IjZiZmMyNjdkLTliY2EtNGY5MS1hNGM2LTFiZWZlZmI3OWQ2MyIsImV4cCI6MTcxMjcwMzg2NH0.f-R_TVj9qFLNnIUvj8yKh9NH0o1aYDXmyHAMr-MjuUU5Fj7XC3IlmCuKXGT46_5zsydQfWUsjfn9ngkip8Vf70pz6utwANFd-MUqOla1toDETtxPQ0nLbHhL_sqx-scfM6-vcz4VufCgAwabR6bTUn7oL0LMv4twNeKHUpXcHjcjjfpMik4E1o_Cbw0lbtqtAyM52uih_OttrIolZAHgmQLubukJa7WHZsehU0kLiaqZsIfgOM7v2F5nTz5AfbbwrlRp4loWcoVSD2B5GdNzlZwhgdRQUq17RZvpR3Ew-8f4MXwlxWglR7MQZGylZAsbLt-rfBs8_nBbakRbX4rPLQ-EJQJS2-Y0PpnHR6z6DAxnD3wTEb_yTL557c9spwcGKcd-9ZLXZxTSZD6vNCxhVpfbSTovLoP1Scjd4K8oDd9RIEV-rJXBcHYHYZm8CcUywoH_pf6yCaf9zTevHJ4r34yyTX7YgRNmKU5M2wBvH6EHjCo_VE7-7GLzMGE_CdrwzUU5Ib3X6TDS13epECXJ34XTI0Z6n-f_-4zAJikpftMCILVJ91MYlMA8rYHzWScZFBMtlx61Etx4gPqCDx73pK8A0t6Wj_7xWJNJ1ShfK9BCOyB3iG0n4VXWObeseQ", "scope": "*" } |
Informações | |||||
---|---|---|---|---|---|
| |||||
A partir da versão 12.1.2311, é retornado o refresh_token como parâmetro para que o token de acesso possa ser regerado sem a necessidade de efetuar uma nova autenticação.
|
/btb"
} |
Autorização
De posse com o token JWT gerado na etapa anterior, para acessar determinados recursos / endpoint, bastaria enviar o token de acesso (access_token) na requisição como Bearer na header Authorization.com o formato Bearer Token:
Exemplo:Exemplo...
Método: GET
URL: http://{{host}}:{{port}}/api/btb/v1/properties/general
Authorization: Bearer (Informar o access_ token JWT)
Image Added
Dica | ||
---|---|---|
| ||
Nesta etapa são realizados diversas validações de autorização ao recurso / endpoint, tais como a integridade do Token JWT, validade, escopo e audiência, onde todas as informações necessárias já estariam presentes no próprio token. Possíveis status de retorno:
|
|
O modelo Resource Owner Password Credentials pode ser utilizado em portais pois vincula o token com um usuário do ERP.
A seguir serão demonstrados alguns trechos de códigos em JavaScript e TypeScript para exemplificar uma utilização no produto. Lembrando que o código pode ser alterado de acordo com a linguagem de programação utilizada, pois é necessário seguir somente os conceitos gerais de Autenticação (para gerar o token) e Autorização (validação do token).
Login
Após efetuar a ação do login, o mesmo deve executar o endpoint de geração do token, onde seu resultado pode ser armazenado no localStorage do navegador para utilizações posteriores.
No trecho de código abaixo, caso o token seja gerado com sucesso, seu retorno é armazenado no localStorage com a chave token-service.token.
Bloco de código | ||
---|---|---|
| ||
function login_oauth2() {
var http = new XMLHttpRequest();
var url = '/totvs-login-oauth2/oauth2/token?grant_type=password';
http.open('POST', url, true);
http.setRequestHeader('Authorization', "Basic " + btoa($txtUsername.val()+":"+$txtPassword.val()));
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
localStorage.setItem("token-service.token", http.responseText);
}
}
} |
Geração dos tokens durante a utilização
Para limitar o uso indevido em caso de vazamentos, todos os tokens expiram (tempo parametrizável no ERP Datasul), por este motivo é importante que durante a utilização do portal os tokens sejam continuamente revalidados.
Com o intuito de facilitar a geração do token dentro do produto, é recomendado a utilização do refresh_token:
Image Removed
Método: POST
URL: http://{{host}}:{{port}}/totvs-login-oauth2/oauth2/token?grant_type=refresh_token
Authorization: Não informar pois é considerada somente a validação do token
Body (x-www-form-urlencoded):
- refresh_token (Obrigatório): Enviar como x-www-form-urlencoded, o refresh_token gerado no login do produto.
Nota | ||
---|---|---|
| ||
|
No trecho de código abaixo é demonstrado a geração contínua de um token (com base no refresh_token), sendo executada em um ciclo continuo 60 segundos antes de sua expiração:
Bloco de código |
---|
$scope.refreshToken = function() {
var http = new XMLHttpRequest();
var url = '/totvs-login-oauth2/oauth2/token?grant_type=refresh_token';
var params = `refresh_token=${$scope.getRefreshToken()}`;
http.open('POST', url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
localStorage.setItem("token-service.token", http.responseText);
}
}
http.send(params);
};
$scope.getExpiresInToken = function() {
const tokenService = localStorage.getItem('token-service.token');
let jsonTokenService = JSON.parse(tokenService);
return jsonTokenService['expires_in'];
};
$scope.getRefreshToken = function() {
const tokenService = localStorage.getItem('token-service.token');
let jsonTokenService = JSON.parse(tokenService);
return jsonTokenService['refresh_token'];
};
var expireIn = $scope.getExpiresInToken() * 1000;
/**
* 1 minuto antes de expirar o token, tenta efetuar a renovacao
*/
setInterval(async() => {
await $scope.refreshToken()
}, (expireIn - (60 * 1000))); |
Utilização dos tokens para acessos aos recursos
Com o token disponível no localStorage e continuamente validado pelo refresh_token, para efetuar o acesso a determiados recrusos, basta resgatar o valor do access_token e envia-lo na requisição desejada.
O trecho de código abaixo demonstra o envio do token na URL devido as características deste endpoint (Smart View), porém este mesmo conceito pode ser adaptado com o modelo Authorization Bearer para acessar os endpoints do ERP Datasul.
Bloco de código | ||
---|---|---|
| ||
public onSmartView(smLayout: SmartViewLayout): void {
let jwtToken = this.getAccessToken();
let urlView = `${this.urlSmartView}reports/${smLayout["id"]}/view?access_token=${jwtToken}&hidemenus=true&expires_in=0&token_type=bearer`;
this.link = this.sanitizer.bypassSecurityTrustResourceUrl(urlView);
this.poPageSlide.open();
}
private getAccessToken(): String {
let tokenService = localStorage.getItem('token-service.token');
let jsonTokenService = JSON.parse(tokenService);
return jsonTokenService['access_token'];
} |