Clipper On Line • Ver Tópico - Autenticação OAuth2

Autenticação OAuth2

Projeto HwGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

 

Autenticação OAuth2

Mensagempor Adson » 11 Ago 2021 08:16

Olá, senhores(as):

Estou implementando uma integração com uma API que usa o método de autenticação OAuth2 e não estou tendo sucesso.

Detalhes da API:

"A comunicação com a API é realizada utilizando os padrões de arquitetura REST, trafegando mensagens no padrão JSON em codificação UTF-8.
Para que os retornos de erro estejam em formato adequado para leitura, padrão JSON, é necessário enviar o Header Accept: application/json"


Alguém tem um exemplo, usando o xHarbour para disponibilizar ?

Esse é o método que uso para fazer a conexão (As variáveis cURL, cClientID e cClientSecret são devidamente preenchidas no método construtor. A variável cTipo, contém o comando PUT/GET):
METHOD Comunica() CLASS TMetodosAPI

LOCAL oServer, nPos := 0, cJSon

   // Definição do arquivo JSon com as credenciais
   cJSon := '{' +;
            '"grant_type":"client_credentials",' +;
            '"scope":"partner_all",' +;
            '"client_id":'      + AspaDupla( ::cClientID )      + ',' +;
            '"client_secret":'  + AspaDupla( ::cClientSecret )  +;
            '}'

   oServer:=CreateObject( "MSXML2.ServerXMLHTTP")
   oServer:Open( ::cTipo, ::cUrl, .F. )
   oServer:SetRequestHeader("accept", "application/json")
   oServer:setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")

   TRY
      oServer:Send(cJson)
      oServer:WaitForResponse( 1000 )
   CATCH
      ::nCode := 503
      Return
   END
   
   ::nCode := oServer:status
   
   hb_jsonDecode( oServer:ResponseBody, @::aResultado )
   
   Return
Avatar de usuário

Adson
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 23
Data de registro: 05 Mar 2019 10:36
Cidade/Estado: GOIANIA/GO
Curtiu: 19 vezes
Mens.Curtidas: 3 vezes

Autenticação OAuth2

Mensagempor JoséQuintas » 11 Ago 2021 13:07

Tá parecido com o que tentamos descobrir aqui:

http://www.pctoledo.com.br/forum/viewtopic.php?f=4&t=25795
José M. C. Quintas
Harbour 3.4, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, hbnetio, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"
Avatar de usuário

JoséQuintas
Colaborador

Colaborador
 
Mensagens: 17601
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 13 vezes
Mens.Curtidas: 956 vezes

Autenticação OAuth2

Mensagempor Adson » 30 Ago 2021 08:20

Consegui resolver o problema da comunicação
O código ficou assim:
CLASS TClasseHTTP
********************************************************************************

   DATA cURL            INIT ""
   DATA cClientID       INIT ""
   DATA cClientSecret   INIT ""
   DATA aResultado      INIT Hash()
   DATA cTokenTemp      INIT ""                // Token provisório
   DATA cTokenType      INIT ""                // Token provisório
   DATA tTokenExpira    INIT CTOT("")          // Data e hora que o token expira
   DATA cPedido         INIT ""                // Número do pedido
   DATA nStatusPed      INIT 0                 // Código do status do pedido
   DATA cStatusPed      INIT ""                // Descrição do status to pedido
   DATA cMetodoPed      INIT ""                // Descrição do método para atualizar o pedido (received, invoiced, tracking, trancking-steps, canceled)
   DATA cJSonFile       INIT ""                // Arquivo JSon que contém as informações enviadas
   DATA nCode           INIT ""                // Código de retorno
   DATA cMsg            INIT ""                // Mensagem de retorno
   DATA cTipo           INIT ""                // Tipo de comunicação PUT/GET/POST
   DATA cServico        INIT ""                // Tipo de serviço a ser acessado
   DATA lSalvaRet       INIT .F.               // Indica se é pra salvar o retorno ou não

   METHOD New() CONSTRUCTOR

   METHOD LimparOfertas()
   METHOD EnviarOfertas()
   METHOD BaixarPedidos()
   METHOD EnviarPedidos()
   
   METHOD ObterToken()
   METHOD GetPostAPI()

ENDCLASS

********************************************************************************
METHOD New() CLASS TClasseHTTP
********************************************************************************

   ::cURL            := ALLTRIM(USER->FA_URL)
   ::cClientID       := ALLTRIM(USER->FA_ID)
   ::cClientSecret   := ALLTRIM(USER->FA_SECRET)
   ::aResultado      := Hash()
   ::cTokenTemp      := ""
   ::cTokenType      := ""
   ::tTokenExpira    := CTOT("")
   ::cPedido         := ""
   ::nStatusPed      := 0
   ::cStatusPed      := ""
   ::cMetodoPed      := ""
   ::cJSonFile       := ""
   ::nCode           := ""
   ::cMsg            := ""
   ::cTipo           := ""
   ::cServico        := ""
   ::lSalvaRet       := .T.
   
RETURN( SELF )

*********************************************************************************
*
*  Limpa todas as ofertas disponíveis no site.
*
*********************************************************************************
METHOD LimparOfertas() CLASS TClasseHTTP

   If DATETIME() >= ::tTokenExpira
      ::ObterToken()
   EndIf   

   If !EMPTY( ::cTokenTemp )

      ::cServico := "/partner/v1/settings/reset-offers"
      ::cTipo    := "GET"
      ::GetPostAPI()

   EndIf   

   Return

*********************************************************************************
*
*  Envia a oferta do produto (pode enviar lote de 1000 registros)
*
*********************************************************************************
METHOD EnviarOfertas() CLASS TClasseHTTP

   If DATETIME() >= ::tTokenExpira
      ::ObterToken()
   EndIf   

   If !EMPTY( ::cTokenTemp )

      ::cServico := "/partner/v1/offer/ean"
      ::cTipo    := "PUT"
      ::GetPostAPI()

   EndIf   

   Return

*********************************************************************************
*
*  Baixa pedidos por situação
*
*********************************************************************************
METHOD BaixarPedidos() CLASS TClasseHTTP

   If DATETIME() >= ::tTokenExpira
      ::ObterToken()
   EndIf   

   If !EMPTY( ::cTokenTemp )

      ::cServico := "/partner/v1/order/list/"+ALLTRIM(STR(::nStatusPed))
      ::cTipo    := "GET"
      ::GetPostAPI()

   EndIf   

Return

*********************************************************************************
*
*  Envia informações do pedido pro portal
*
*********************************************************************************
METHOD EnviarPedidos() CLASS TClasseHTTP

LOCAL vCorpo := ""

   vJSonFile := ""
   
   If DATETIME() >= ::tTokenExpira
      ::ObterToken()
   EndIf   

   If !EMPTY( ::cTokenTemp )

      ::cServico  := "/partner/v1/order/" + ::cPedido + '/' + ::cMetodoPed
      ::cTipo     := "PUT"

      If ::cMetodoPed == "tracking"

         vCorpo :=  '"courier_title": "proprio",' +;
                    '"tracking_code": "",' +;
                    '"tracking_url": "", ' +;
                    '"finished": true'

      ElseIf ::cMetodoPed == "invoiced"

         vCorpo := '"invoice_number":'  + AspaDupla( FA_PEDCAB->NR_NOTAVEN )                     + ',' +;
                   '"invoice_url":'     + AspaDupla( ObtemURLConsulta( FA_PEDCAB->SG_UF, '1' ) ) + ',' +;
                   '"invoice_key":'     + AspaDupla( FA_PEDCAB->NR_CHNFE )                       + ',' +;
                   '"invoice_value":'   + AspaDupla( ALLTRIM(STR(FA_PEDCAB->VR_LIQPED,10,2)) )

      EndIf

      If !EMPTY( vCorpo )
         vJSonFile   := STRZERO( HB_RandomInt( 999999 ), 6 )+".JSON"
         ::cJSonFile := vpUserDir+"\ENV_"+vJSonFile
         vCorpo := '{' + vCorpo + '}'
         MemoWrit( ::cJSonFile, vCorpo, .F. )
      EndIf

      ::GetPostAPI()

      If ::nCode = 200 .AND. FILE( ::cJSonFile )
         FErase( ::cJSonFile )
      EndIf

   EndIf
   
   Return

*******************************************************
*
* Obtém um novo token.
*
*******************************************************
METHOD ObterToken() CLASS TClasseHTTP

LOCAL oServer, nPos := 0, cCredentials, nExpireTime := 0
   
   ::cTokenTemp   := ""
   ::cTokenType   := ""
   ::tTokenExpira := CTOT("")
   ::aResultado   := Hash()
   ::nCode        := 0
   
   oServer:=CreateObject( "MSXML2.ServerXMLHTTP" )

   oServer:Open( "POST", ::cURL + "/oauth2/token", .F. )
   oServer:setRequestHeader( "Content-Type",    "application/x-www-form-urlencoded; charset=utf-8")
   oServer:SetRequestHeader( "accept",          "*/*" )
   oServer:SetRequestHeader( "Accept-Encoding", "gzip, deflate, br" )
   oServer:SetRequestHeader( "Connection",      "keep-alive" )
   
   cCredentials := "client_id=" + ::cClientID + ;
                   "&client_secret=" + ::cClientSecret + ;
                   "&grant_type=client_credentials" + ;
                   "&scope=partner_all"

   TRY
      oServer:Send(cCredentials)
      oServer:WaitForResponse( 1000 )
   CATCH
      FA_GravarLog( "OBTÉM TOKEN TRY CATCH (FALHA)" + LF + valtoprg( oServer:ResponseBody ) )
      MsgExclamation("Falha ao obter um novo token de acesso (TRY CATCH)"+LF+LF+;
                     "Tente novamente mais tarde", PROCNAME() )
      Return
   END
   
   ::nCode := oServer:status
   nPos    := aScan( aCode, {|x| x[1] == ::nCode } )
   
   If nPos > 0
      ::cMsg  := aCode[nPos,2]
   Else
      ::cMsg  := 'CÓDIGO DE RETORNO NÃO ENCONTRADO '+STR(::nCode,3)
   EndIf
   
   hb_jsonDecode( oServer:ResponseBody, @::aResultado )

   // Salva o retorno
   If ::lSalvaRet
      If EMPTY( vJSonFile )
         vJSonFile := STRZERO( HB_RandomInt( 999999 ), 6 )+".JSON"
      EndIf   
      MemoWrit(vpUserDir+"\RET_TOKEN_"+vJSonFile, oServer:ResponseText, .F.)
   Endif

   If HHasKey(::aResultado,'access_token')
      ::cTokenTemp := ::aResultado['access_token']
   endif

   If HHasKey(::aResultado,'token_type')
      ::cTokenType := ::aResultado['token_type']
   endif

   If HHasKey(::aResultado,'expires_in')
      nExpireTime := ::aResultado['expires_in']
   endif

   // Salva as informações do token obtido
   If !EMPTY( ::cTokenTemp )
      ::tTokenExpira := DATETIME() + ( nExpireTime/24/60/60 )
   Else
      FA_GravarLog( "OBTÉM TOKEN (FALHA)" + LF + valtoprg( oServer:ResponseBody ) )
      MsgExclamation("Falha ao obter um novo token de acesso"+LF+LF+;
                     STR(::nCode,3)+" - "+::cMsg, PROCNAME() )
   EndIf

   Return

********************************************************************************
*
*  Executa métodos PUT/GET/POST usando o token
*
********************************************************************************
METHOD GetPostAPI() CLASS TClasseHTTP
********************************************************************************
LOCAL oServer, nPos := 0, cJSon

   ::aResultado := HASH()
   
   oServer:=CreateObject( "MSXML2.ServerXMLHTTP" )
   oServer:Open( ::cTipo, ::cUrl + ::cServico, .F. )
   oServer:setRequestHeader( "Content-Type",    "application/json" )
   oServer:SetRequestHeader( "Authorization",   ::cTokenType+" "+::cTokenTemp )   

   // Antes de executar o método, o arquivo JSon é salvo no caminho apontado por ::cJSonFile
   If !EMPTY( ::cJSonFile )
      cJSon := MemoRead( ::cJSonFile )
   EndIf

   TRY
      oServer:Send( cJSon )
      oServer:WaitForResponse( 1000 )
   CATCH
      MemoWrit(vpUserDir+"\RET_"+::cTipo+"_CATCH_"+vJSonFile, oServer:ResponseBody, .F.)
      ::nCode := 503
      nPos    := aScan( aCode, {|x| x[1] == ::nCode } )
      ::cMsg  := aCode[nPos,2]
      return
   END

   ::nCode := oServer:status
   nPos    := aScan( aCode, {|x| x[1] == ::nCode } )

   If nPos > 0
      ::cMsg := aCode[nPos,2]
   Else
      ::cMsg := 'CÓDIGO DE RETORNO NÃO ENCONTRADO '+STR(::nCode,3)
   EndIf

   hb_jsonDecode( oServer:ResponseBody, @::aResultado )
   
   // Salva o retorno
   If ::lSalvaRet
      If EMPTY( vJSonFile )
         vJSonFile := STRZERO( HB_RandomInt( 999999 ), 6 )+".JSON"
      EndIf   
      MemoWrit(vpUserDir+"\RET_"+::cTipo+"_"+vJSonFile, oServer:ResponseText, .F.)
   EndIf
   
   Return
Avatar de usuário

Adson
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 23
Data de registro: 05 Mar 2019 10:36
Cidade/Estado: GOIANIA/GO
Curtiu: 19 vezes
Mens.Curtidas: 3 vezes




Retornar para HwGui

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 3 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro