PC SOFT

PROFESSIONAL NEWSGROUPS
WINDEVWEBDEV and WINDEV Mobile

Home → WINDEV 25 → Estudos sobre Apis Rest Send com WLanguage - Diferentes tipos de autenticação
Estudos sobre Apis Rest Send com WLanguage - Diferentes tipos de autenticação
Started by Boller, Apr., 03 2025 8:51 AM - No answer
Registered member
4,520 messages
Posted on April, 03 2025 - 8:51 AM
Bom dia!

Vamos explorar os tipos de autenticação disponíveis para APIs REST no ambiente WLanguage. Este é um tema super importante para garantir segurança nas suas aplicações!

# Tipos de Autenticação em APIs REST com WLanguage

## 1. Basic Authentication
A mais simples, mas nem sempre a mais segura! 😅

//##############################
// Exemplo de chamada com Basic Authentication
PROCEDURE ConsumoAPIBasicAuth(Usuario is string, Senha is string)
// Prepara a requisição
RESTRequete is httpRequest

// Configura a autenticação básica
RESTRequete.AuthenticationBasic(Usuario, Senha)

// Configura a URL e método
RESTRequete.URL = "https://api.exemplo.com/recurso"
RESTRequete.Method = httpGet

// Executa a requisição
RESTResposta is httpResponse = HTTPSend(RESTRequete)

// Verifica o resultado
IF RESTResposta.StatusCode = 200
Info("Sucesso: " + RESTResposta.Content)
ELSE
Error("Erro na requisição: " + RESTResposta.StatusCode)
END//IF

RESULT RESTResposta
//##############################

## 2. Bearer Token / JWT (JSON Web Token)
Mais moderno e seguro! É o queridinho das APIs! 🚀

//##############################
// Consumo de API com Bearer Token/JWT
PROCEDURE ConsumoAPIBearerToken(Token is string)
// Prepara a requisição
RESTRequete is httpRequest

// Adiciona o token no cabeçalho
RESTRequete.AddHeader("Authorization", "Bearer " + Token)

// Configura a URL e método
RESTRequete.URL = "https://api.exemplo.com/dados"
RESTRequete.Method = httpGet

// Executa a requisição
RESTResposta is httpResponse = HTTPSend(RESTRequete)

// Verifica e processa a resposta
IF RESTResposta.StatusCode = 200
// Processa os dados JSON recebidos
JsonDados is JSON = JSONToValue(RESTResposta.Content)
Trace(JsonDados)
ELSE
Error("Falha na autenticação: " + RESTResposta.StatusCode)
END//IF

RESULT RESTResposta
//##############################

## 3. API Key
Perfeito para APIs públicas com controle de acesso!

//##############################
// Consumo de API com API Key
PROCEDURE ConsumoAPIKey(APIKey is string)
// Prepara a requisição
RESTRequete is httpRequest

// Duas formas comuns de passar a API Key:

// 1. Via parâmetro na URL
RESTRequete.URL = "https://api.exemplo.com/dados…=" + APIKey

// 2. Via cabeçalho (mais seguro)
RESTRequete.AddHeader("X-API-Key", APIKey)

RESTRequete.Method = httpGet

// Executa a requisição
RESTResposta is httpResponse = HTTPSend(RESTRequete)

// Verifica o resultado
IF RESTResposta.StatusCode = 200
Info("Dados recebidos com sucesso!")
ELSE
Error("Falha na requisição: " + RESTResposta.StatusCode)
END//IF

RESULT RESTResposta
//##############################

## 4. OAuth 2.0
O mais completo e robusto! Ideal para aplicações empresariais! 💼

//##############################
// Implementação básica de OAuth 2.0
PROCEDURE ConsumoAPIOAuth2(ClientID is string, ClientSecret is string, RedirectURI is string)
// 1. Obter código de autorização (geralmente via navegador)
UrlAutorizacao is string = [
https://auth.servico.com/oauth2/authorize?
client_id=[%ClientID%]&
redirect_uri=[%RedirectURI%]&
response_type=code&
scope=read
]

// Abre navegador ou webview para autenticação do usuário
// (Código de UI omitido por brevidade)

// 2. Trocar código por token de acesso (após callback)
CodigoAutorizacao is string = "..." // Obtido do callback

TokenRequest is httpRequest
TokenRequest.URL = "https://auth.servico.com/oauth2/token"
TokenRequest.Method = httpPost
TokenRequest.ContentType = "application/x-www-form-urlencoded"

// Prepara os dados do formulário
TokenRequest.Data = [
client_id=[%ClientID%]&
client_secret=[%ClientSecret%]&
grant_type=authorization_code&
code=[%CodigoAutorizacao%]&
redirect_uri=[%RedirectURI%]
]

TokenResposta is httpResponse = HTTPSend(TokenRequest)

IF TokenResposta.StatusCode = 200
// Extrai o token de acesso da resposta JSON
TokenJSON is JSON = JSONToValue(TokenResposta.Content)
AccessToken is string = TokenJSON.access_token
RefreshToken is string = TokenJSON.refresh_token

// 3. Usar o token para acessar a API
APIRequest is httpRequest
APIRequest.URL = "https://api.servico.com/recursos"
APIRequest.Method = httpGet
APIRequest.AddHeader("Authorization", "Bearer " + AccessToken)

APIResposta is httpResponse = HTTPSend(APIRequest)

IF APIResposta.StatusCode = 200
// Sucesso! Processa dados...
Info("Dados recebidos via OAuth 2.0!")
END
END

// Estrutura para armazenar tokens e informações
RESULT TokenJSON
//##############################

## 5. HMAC (Hash-based Message Authentication Code)
Excelente para verificação de integridade! Assinatura digital das requisições! 🔐

//##############################
// Autenticação HMAC
PROCEDURE ConsumoAPIHMAC(ChaveSecreta is string, Dados is string)
// Obter timestamp atual para evitar replay attacks
Timestamp is string = Now()

// Concatenar dados a serem assinados
DadosParaAssinar is string = Timestamp + Dados

// Calcular a assinatura HMAC usando SHA-256
Assinatura is string = HMACSHA256(DadosParaAssinar, ChaveSecreta)

// Convertendo para Base64 para transmissão
AssinaturaBase64 is string = Encode(Assinatura, encodeBASE64)

// Preparar a requisição
RESTRequete is httpRequest
RESTRequete.URL = "https://api.exemplo.com/dados"
RESTRequete.Method = httpPost
RESTRequete.ContentType = "application/json"

// Adicionar cabeçalhos de autenticação
RESTRequete.AddHeader("X-API-Timestamp", Timestamp)
RESTRequete.AddHeader("X-API-Signature", AssinaturaBase64)

// Corpo da requisição
RESTRequete.Data = Dados

// Enviar a requisição
RESTResposta is httpResponse = HTTPSend(RESTRequete)

// Verificar resultado
IF RESTResposta.StatusCode = 200
Info("Autenticação HMAC bem-sucedida!")
ELSE
Error("Falha na autenticação HMAC: " + RESTResposta.StatusCode)
END

RESULT RESTResposta
//##############################

## 6. Autenticação Mútua SSL/TLS (mTLS)
Para segurança em nível empresarial! É como um handshake digital entre cliente e servidor. 🤝

//##############################
// Autenticação mTLS
PROCEDURE ConsumoAPImTLS(CaminhoCertificado is string, SenhaCertificado is string)
// Prepara a requisição com certificado
RESTRequete is httpRequest

// Configuração do certificado SSL para autenticação mútua
RESTRequete.Certificate = CaminhoCertificado
RESTRequete.CertificatePassword = SenhaCertificado

// Configurar a requisição
RESTRequete.URL = "https://api.segura.com/dados"
RESTRequete.Method = httpGet

// Envio com validação SSL completa
RESTResposta is httpResponse = HTTPSend(RESTRequete)

IF RESTResposta.StatusCode = 200
Info("Autenticação mTLS bem-sucedida!")
ELSE
Error("Falha na autenticação mTLS: " + RESTResposta.StatusCode)
END

RESULT RESTResposta
//##############################

## 7. Custom Authentication (Personalizada)
Para quando você precisa de algo único para seu negócio! 🎯

//##############################
// Exemplo de autenticação personalizada
PROCEDURE ConsumoAPICustomAuth(UsuarioID is string, AppID is string, CustomKey is string)
// Gera hash único baseado em vários fatores
HashUnico is string = SHA256(UsuarioID + "|" + AppID + "|" + Today() + "|" + CustomKey)

// Prepara a requisição
RESTRequete is httpRequest
RESTRequete.URL = "https://api.personalizada.com/dados"
RESTRequete.Method = httpGet

// Adiciona os cabeçalhos personalizados
RESTRequete.AddHeader("X-User-ID", UsuarioID)
RESTRequete.AddHeader("X-App-ID", AppID)
RESTRequete.AddHeader("X-Auth-Hash", HashUnico)

// Executa a requisição
RESTResposta is httpResponse = HTTPSend(RESTRequete)

// Verifica o resultado
IF RESTResposta.StatusCode = 200
Info("Autenticação personalizada aceita!")
ELSE
Error("Falha na autenticação personalizada: " + RESTResposta.StatusCode)
END

RESULT RESTResposta
//##############################

## Comparativo com Python:
Em Python, você precisa geralmente usar bibliotecas como `requests` para fazer algo similar, mas WLanguage já tem todos esses recursos nativamente! Menos código, menos bugs, mais diversão! 😄

## Exemplo de CASO REAL: Implementação de autenticação completa para sua API

//##############################
// Classe de gestão de autenticação para API
CLASSE APIAuthManager
PRIVATE
m_TokenValidade is datetime
m_AccessToken is string
m_RefreshToken is string
m_APIEndpoint is string
m_ClientID is string
m_ClientSecret is string

PUBLIC
PROCEDURE Constructor(Endpoint is string, ClientID is string, ClientSecret is string)
m_APIEndpoint = Endpoint
m_ClientID = ClientID
m_ClientSecret = ClientSecret
END

// Método para obter token válido (reutiliza ou renova conforme necessário)
PROCEDURE ObterTokenValido()
// Verifica se já temos um token válido
IF m_AccessToken <> "" AND m_TokenValidade > Now()
RESULT m_AccessToken
END

// Precisamos de um novo token
IF m_RefreshToken <> ""
// Tenta usar o refresh token primeiro
IF RenovarComRefreshToken() = True
RESULT m_AccessToken
END
END

// Sem token ou refresh falhou, faz login completo
IF ObterNovoToken() = True
RESULT m_AccessToken
ELSE
Error("Falha na autenticação!")
RESULT ""
END
END

// Método para renovar com refresh token
PRIVATE PROCEDURE RenovarComRefreshToken()
TokenRequest is httpRequest
TokenRequest.URL = m_APIEndpoint + "/oauth2/token"
TokenRequest.Method = httpPost
TokenRequest.ContentType = "application/x-www-form-urlencoded"

// Preparando dados para o refresh
TokenRequest.Data = [
grant_type=refresh_token&
refresh_token=[%m_RefreshToken%]&
client_id=[%m_ClientID%]&
client_secret=[%m_ClientSecret%]
]

TokenResposta is httpResponse = HTTPSend(TokenRequest)

IF TokenResposta.StatusCode = 200
// Processa resposta
TokenJSON is JSON = JSONToValue(TokenResposta.Content)
m_AccessToken = TokenJSON.access_token

// Atualiza o refresh token se fornecido
IF TokenJSON.refresh_token <> Null
m_RefreshToken = TokenJSON.refresh_token
END

// Calcula validade
ValidadeSegundos is int = TokenJSON.expires_in
m_TokenValidade = DateTimeAddSecond(Now(), ValidadeSegundos)

// Salva os tokens para uso futuro (encriptados!)
SalvarTokensSeguro()

RESULT True
END

// Se chegou aqui, falhou
RESULT False
END

// Método para obter novo token
PRIVATE PROCEDURE ObterNovoToken()
// Implementação do fluxo completo de obtenção de token
// (Simplificado por brevidade)

RESULT False // Placeholder
END

// Método para salvar tokens de forma segura
PRIVATE PROCEDURE SalvarTokensSeguro()
// Encripta tokens antes de salvar
TokensEncriptados is string = Encrypt(m_AccessToken + "|" + m_RefreshToken, "AES", GetUUID())
// Salva em armazenamento seguro
// ...
END
END//Classe
//##############################

## Recomendações de Segurança:

1. **Nunca armazene tokens ou credenciais em texto claro** - use Encrypt() para proteger dados sensíveis!
2. **Sempre verifique o SSL/TLS** - evite bypass de verificação SSL em produção!
3. **Implemente limites de tentativas** - proteja contra ataques de força bruta!
4. **Considere implementar JWTRS256** - mais seguro que JWT padrão para casos críticos!
5. **Use tempos de expiração curtos para tokens** - reduz o impacto em caso de roubo!

O WLanguage da versão 28 traz recursos poderosos de segurança para implementar qualquer um desses métodos de autenticação. Muito mais simples que Python, C# ou outras linguagens! 🚀

--
Adriano José Boller
______________________________________________
Consultor e Representante Oficial da
PcSoft no Brasil
+55 (41) 99949 1800
adrianoboller@gmail.com
skype: adrianoboller
http://wxinformatica.com.br/