Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

CONTEÚDO

Informações

Índice
maxLevel4
minLevel2
indent50px
absoluteUrltrue

01. 

VISÃO GERAL

Visão Geral

Disponibilizar 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

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

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

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 geração e acesso ao endpoint será concedido de acordo com a especificidade do modelo OAuth2

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 modelos de autenticação:

  • Client Credentials (OAuth2 - Client Credentials)
  • Resource Owner Password Credentials (
    • e regras de seguranças interna (certificado, audiência e escopo).



    03. Exemplos de Utilização

    Dica

    Antes de iniciar a implementação, verifique qual o modelo é o mais adequado para as concessões de acesso, com base no melhor modelo de segurança,

    Consulte os links: OAuth2 - Client Credentials e OAuth2 - Resource Owner Password Credentials

    )
    03. EXEMPLO DE UTILIZAÇÃO

    para mais informações.

    a. 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.

    CFG - OAuth2Configura os modelos (Grant Type) de autenticação do usuário propostos nesta documentação.
    CFG - JWTConfigura o modelo do Token JWT que será gerado caso a autenticação seja realizada com sucesso.

    b. 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:



    Informações

    A seguir serão demonstrados alguns trechos de códigos em JavaScript e TypeScript que exemplificam os conceitos gerais de Autenticação (para gerar o token) e Autorização (validação do token ao requisitar um endpoint).

    Lembrando que o código deve ser alterado de acordo com a linguagem de programação e regras específicas de segurança.

    b. Client Credentials


    Nota

    Este modelo é recomendado quando há a necessidade de comunicações machine-to-machine pois não há um vínculo do usuário do ERP Datasul com a requisição, consequentemente não ocorrerá alguns relacionamentos como o direcionamento do broker, setar um usuário e empresa na memória do PASOE, entre outros. 

    Geração do token

    De posse com as credenciais de acesso (Id cliente e Senha cliente) cadatradas na tela de Propriedades → OAuth2 → Client Credentials, pode-se efetuar a requisição para a geração dos tokens

    Método: POST

    URL: http://{{host}}:{{port}}/totvs-login-oauth2/oauth2/token?grant_type=client_credentials

    Authorization: Basic Auth (Informar as credenciais Id cliente, Senha cliente parametrizadas em Propriedades → OAuth2)

    Aviso
    titleAviso

    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
    languageruby
    titleExemplo do retorno Body
    linenumberstrue
    {
        "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
    titleNota

    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: GET

    URL: http://{{host}}:{{port}}/api/btb/v1/properties/general

    Authorization: Bearer (Informar o token JWT)

    Dica
    titleDica

    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:

    • 200 (OK): Acesso permitido ao recurso com os dados retornados;
    • 401 (Unauthorized): O token informado não é valido;
    • 403 (Forbidden): O token é valido porém há restrição em seu uso (escopo ou audiência);
    • 500 (Internal Server Error): Ocorreu um erro no servidor de aplicação Web (Tomcat) ou AppServer.

    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

    AuthorizationBasic 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
    titleAviso

    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.  

    Caso a autenticação seja realizada com sucesso, é retornado o token com o formato abaixo:

    Bloco de código
    languageruby
    titleExemplo do retorno Body
    linenumberstrue
    {
        "access_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJzdXBlciIsImlhdCI6MTY1NjUyOTkzNCwiZXhwIjoxNjU2NTMwMDU0LCJhdWQiOiJqd3QuaW8uYXBhY2hlLmV4dGVybm8iLCJ0ZW5hbnRJZCI6ImY3N2Q4ZjM2LTQzYzYtOWJiMS05NzE0LWQyMTBhOGI1MzcwYSIsInNjb3BlIjpbIioiXX0.b43eHEra_xjGZqkSIC6h1m7ZamFxb1jcAKCDjyWvOh7VjWE5QZkwnozTtAudQSGE3CaT-R8A1xofERqhymnPKX-me1OnTbcMoRwFMSd76w1AF9mT9U262X8noZcqyQ89-wmav93w-CnFpCek_-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
    languageruby
    titleExemplo do retorno Body
    linenumberstrue
    {
        "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",
        "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
    languageruby
    titleExemplo do retorno Body
    linenumberstrue
    {
        "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",
        "scope": "*"
    }
    Informações
    titleInformação

    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.

    Bloco de código
    languageruby
    {
        "access_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJmMDkzNTQwOC1hZThjLTBlYWUtYWExNC03MzA2OGM3ZjQwZTAiLCJpYXQiOjE2OTI2NDczMTAsImlzc3VlciI6ImRhdGFzdWwiLCJpc3MiOiJkYXRhc3VsIiwianRpIjoiYTk1YTAzNmMtNjA1OS00YmZhLWJlNTYtYmUxZDk5NGNlM2I4IiwiZXhwIjoxNjkyNjQ3NDkwLCJhdWQiOiJ0ZXN0ZSIsInRlbmFudElkIjoiZjc3ZDhmMzYtNDNjNi05YmIxLTk3MTQtZDIxMGE4YjUzNzBhIiwic2NvcGUiOlsiKiJdfQ.grdplhwM5Q1B2F1G_JYq4UEaY7yHNhp7N60cr1YZwM4Z5qjpT0fqoKALZYnQqKH-YcboCcVrjZ5VFVdOgcMXu6s5w8cKEumLlDEidip67rncAOEyZPZ3tcA053QszaKuhDxBDrOwpmS9xRW6AV7oVGFBDQN2fDZDBl7uUin4Qv5hMXGZvxWtIYoha3pvMGviyupYae9GKA71ZZwvBIDpScbXIhkuroM03MsrdHwypzFYbLrPAmmTITEl_b-Y6v4MekbcE01SfSRrQuXU7tS4pxC3dXyysi_dWUeAFAw8Xdxv4VoNVKkFO2pnmQwGXSOGunES7bbd24DCnFGW0RZa7A",
        "token_type": "Bearer",
        "expires_in": 180,
        "refresh_token": "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJmMDkzNTQwOC1hZThjLTBlYWUtYWExNC03MzA2OGM3ZjQwZTAiLCJpYXQiOjE2OTI2NDczMTAsImlzc3VlciI6ImRhdGFzdWwiLCJqdGkiOiJhY2RjOWFlNC03MTRmLTRiMTYtYTdiYS00ODk1MjM2YjI2YTgiLCJhY2Nlc3NUb2tlbiI6ImE5NWEwMzZjLTYwNTktNGJmYS1iZTU2LWJlMWQ5OTRjZTNiOCIsImV4cCI6MTY5MjY0NzQ5MH0.QDtj1txFGd29humF_d6BmiC2f9ppoUXmFnpWDCuzIZn_VzV6EdMOQxv-rM0OujOuss-Z17HhcppL34wqtu_KWK6dupKr3E35cAkV7zcRfkgduBWyPFXSS4LCKIW5RXRoE8VucaDf0rwF1lcl6I3ZPdqzB8D3okDNirW7h1GO6G5TnWz0bHjdE-ZVFjW8x0JvLJE88TmObgLFaF7zLQTYZQ4VXRik_DueCw9dkBWNYJbr57C0wlYpVF7ZujESeX93IjNjzkw1CfDmLySaFGNCksc5VlRLt4NtoSFfFRhPStK7mmFRYveRu1PkF214xCnsSdK2ftqe4QfnqxsU8KAK8g",
        "scope": "*"
    }

    f. Resource Owner Password Credentials - 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.

    Exemplo...

    Método: GET

    URL: http://{{host}}:{{port}}/api/btb/v1/properties/general

    Authorization: Bearer (Informar o access_token)

    Dica
    titleDica

    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:

    • 200 (OK): Acesso permitido ao recurso com os dados retornados;
    • 401 (Unauthorized): O token informado não é valido;
    • 403 (Forbidden): O token é valido porém há restrição em seu uso (escopo ou audiência);
    • 500 (Internal Server Error): Ocorreu um erro no servidor de aplicação Web (Tomcat) ou AppServer.

    g. Resource Owner Password Credentials - Exemplos de Utilização

    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 (para uso posterior) com a chave token-serviceclient.token. 

    Bloco de código
    languagejs
    function logintoken_client_oauth2credentials() {
    	var http = new XMLHttpRequest();
    	var url = '/totvs-login-oauth2/oauth2/token?grant_type=passwordclient_credentials';
    	http.open('POST', url, true);
    
    	http.setRequestHeader('Authorization', "Basic " + btoa($txtUsername.val()+<id_cliente>":"+$txtPassword.val()))<senha_cliente>);
    
    	http.onreadystatechange = function() {
    		if(http.readyState == 4 && http.status == 200) {
    			localStorage.setItem("token-serviceclient.token", http.responseText);
    		}
    	}
    }
    Geração

    Utilização dos tokens

    durante a utilização

    para acessos aos endpoints

    Com o token disponível no localStorage, para efetuar o acesso a determinados endpoints, basta resgatar o valor do access_token e enviá-lo na requisição desejada.

    Para acessar os endpoints do ERP Datasul, basta enviar o valor do token como Authorization Bearer na requisição.

    Bloco de código
    languagejs
    public onIntegration(): void {
    	let jwtToken = this.getAccessToken();
    	... 
    	<EFETUA A REQUISIÇÃO AO ENDPOINT, O TOKEN DEVE SER ENVIADO COM BEARER AUTHORIZATION>
    	...
    }
    
    private getAccessToken(): String {
    	let tokenService = localStorage.getItem('token-client.token');
    	let jsonTokenService = JSON.parse(tokenService);
    	return jsonTokenService['access_token'];
    }

    Expiração do token

    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 necessário a utilização do refresh_token (grant_type e token):

    Método: POST

    URL: http://{{host}}:{{port}}/totvs-login-oauth2/oauth2/token?grant_type=refresh_token

    AuthorizationNã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
    titleNota
    • O refresh_token não possui atributos de acesso (aud, tenantId, scope), portanto não deve ser utilizado para acessos aos recursos;
    • Todo refresh_token é vinculado a um access_token, sendo deste token os atributos considerados para a nova geração;
    • Por motivos de segurança, após a utilização do refresh_token, o mesmo é automaticamente invalidado;
    • Para considerar um novo ciclo de geração, é necessário considerar os novos tokens gerados a partir do refresh_token.

    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 contínuo 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-serviceclient.token", http.responseText);
    		}
    	}
    	http.send(params);
    };
    
    $scope.getExpiresInToken = function() {
    	const tokenService = localStorage.getItem('token-serviceclient.token');
    	let jsonTokenService = JSON.parse(tokenService);
    	return jsonTokenService['expires_in'];
    };
    
    $scope.getRefreshToken = function() {
    	const tokenService = localStorage.getItem('token-serviceclient.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)));


    c. Resource Owner Password Credentials


    Nota

    Este modelo é recomendado caso o endpoint requisitado necessite de informações do usuário do ERP Datasul.

    A utilização do Resource Owner Password Credentials é similar ao Client Credentials, somente difere na geração do token (autenticação), onde são utilizados outros parametros e um usuário e senha do ERP Datasul.

    Geração do token

    Considere as credenciais de acesso de um usuário do ERP Datasul para a geração do token.

    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
    languagejs
    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);
    		}
    	}
    }

    Utilização dos tokens para acessos aos

    recursos

    endpoints

    Com o token disponível no localStorage e continuamente validado pelo refresh_token, para efetuar o acesso a determiados recrusosdeterminados recursos, basta resgatar o valor do access_token e enviaenviá-lo na requisição desejada.

    O trecho de código abaixo demonstra uma integração com o Smart View (no qual necessita de dados do usuário do ERP Datasul para efetuar o compartilhamento dos layouts por usuário ou grupo).

    O token é enviado pela 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(recomendado) para efetuar a integração com outros Portais ou Apps.

    Bloco de código
    languagejs
    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'];
    }

    Expiração do token

    As etapas de atualização do token são idênticas ao modelo apresentado anteriormente (Client Credentials), no qual deve ser utilizado os mesmos endpoints.