No desenvolvimento full-stack, é comum que a API seja fornecida pelo backend e requer a configuração de cabeçalhos ou tokens para decodificar os parâmetros corretamente. Isso protege a API contra exposição indevida e ajuda a evitar engenharia reversa maliciosa.
A abordagem front end pode ser implementada com Vue.js ou PHP, embora os parâmetros necessários para a decodificação sejam semelhanttes. Cada tecnologia possui seus próprios métodos de processamento.
Exemplo de implementação com Vue.js, focando no núcleo da lógica:
// Interceptor de solicitação para manipulação pré-envio
// Adiciona tokens, criptografa parâmetros de forma unificada
const interceptorSolicitacao = (configuracao) => {
if (!configuracao.headers['Content-Type']) {
configuracao.headers['Content-Type'] = 'application/json;charset=utf-8';
}
const identificadorDispositivo = gerarHashDispositivo(obterIdentificadorUnico());
const tokenAutenticacao = localStorage.getItem('tokenAutenticacao') || '';
const carimboTempo = Date.now();
configuracao.headers["chaveacesso"] = "x7y8z9"; // Assinatura de cabeçalho
configuracao.headers["idProduto"] = obterPIDLocal()
configuracao.headers['idioma'] = obterTipoIdioma() === 'pt' ? 'pt' : obterTipoIdioma()
configuracao.headers['codPais'] = 'BR-BR'
configuracao.headers['canal'] = 'WEBFRONTEND'
configuracao.headers['versao'] = '2.1.0'
configuracao.headers['sistema'] = 'WEBFRONTEND'
configuracao.headers['fusoHorario'] = '-3'
configuracao.headers['plataforma'] = obterPlataforma()
configuracao.headers['codVersao'] = '2.1.0'
configuracao.headers['tokenDispositivo'] = 'WEBFRONTEND'
configuracao.headers['sistemaOperacional'] = 'WEBFRONTEND'
configuracao.headers['deviceId'] = identificadorDispositivo
configuracao.headers['tokenAutenticacao'] = tokenAutenticacao
configuracao.headers['ts'] = carimboTempo
if (configuracao.url) {
configuracao.headers['assinatura'] = calcularAssinatura(configuracao.url, identificadorDispositivo, carimboTempo)
}
const tokenArmazenado = obterTokenLocalStorage('get', 'TOKEN_APP')
if (tokenArmazenado) {
configuracao.headers['tokenAutenticacao'] = tokenArmazenado
}
return configuracao;
};
// Interceptor de resposta para processamento pós-resposta
const interceptorResposta = async (resposta) => {
let dados = resposta.data;
if (typeof dados === "string") {
dados = dados ? JSON.parse(dados) : dados;
} else {
if (dados.informacao != null && dados.informacao !== "") {
let dadosCriptografados = decodificarResposta(dados.informacao);
const dadosCompactados = decodificarBase64(dadosCriptografados)
.split("")
.map((caractere) => caractere.charCodeAt(0));
const arrayCompactado = new Uint8Array(dadosCompactados);
const dadosDescompactados = descompactarDados(arrayCompactado);
dados.informacao = new TextDecoder().decode(dadosDescompactados);
dados.informacao = JSON.parse(dados.informacao);
}
switch (dados.codigo) {
case 2005:
localStorage.removeItem('tokenAutenticacao');
localStorage.removeItem('PERFIL_USUARIO');
return;
}
}
return dados;
};
Exemplo de implementação com PHP, adaptado para integração com WordPress:
<?php
/**
* Classe proxy para requisições a APIs externas.
* Encapsula lógica comum: assinatura, cabeçalhos, decodificação.
*/
require_once get_template_directory() . '/api/Funcoes.php';
class ProxyRequisicao
{
private const URL_BASE_PADRAO = 'http://servidor-api.exemplo.com';
private $urlBase;
public function __construct(?string $urlBase = null)
{
$this->urlBase = rtrim($urlBase ?: self::URL_BASE_PADRAO, '/');
}
public function solicitarGet(string $caminho, string $idDispositivoRaw = '', array $cabecalhosExtras = []): array
{
$caminho = $this->normalizarCaminho($caminho);
$urlCompleta = $this->urlBase . $caminho;
$idDispositivo = $this->resolverIdDispositivo($idDispositivoRaw);
$carimboTempo = (string) round(microtime(true) * 1000);
$assinatura = CalculadorAssinatura::gerar($caminho, $idDispositivo, $carimboTempo, 'chave_secreta123');
$cabecalhos = $this->montarCabecalhos($idDispositivo, $carimboTempo, $assinatura, $cabecalhosExtras);
$resposta = wp_remote_request($urlCompleta, [
'method' => 'GET',
'headers' => $cabecalhos,
'timeout' => 45,
]);
if (is_wp_error($resposta)) {
return [
'status' => 'erro',
'mensagem' => 'falha_na_requisicao',
'dados' => ['erro' => $resposta->get_error_message()],
'timestamp' => (int) $carimboTempo,
];
}
$corpo = wp_remote_retrieve_body($resposta);
return ProcessadorResposta::decodificar($corpo, $idDispositivo, $carimboTempo, $assinatura);
}
public function solicitarPost(string $caminho, string $idDispositivoRaw = '', array $cabecalhosExtras = [], array $dadosPost = []): array
{
$caminho = $this->normalizarCaminho($caminho);
$urlCompleta = $this->urlBase . $caminho;
$idDispositivo = $this->resolverIdDispositivo($idDispositivoRaw);
$carimboTempo = (string) round(microtime(true) * 1000);
$assinatura = CalculadorAssinatura::gerar($caminho, $idDispositivo, $carimboTempo, 'chave_secreta123');
$cabecalhos = $this->montarCabecalhos($idDispositivo, $carimboTempo, $assinatura, $cabecalhosExtras);
$resposta = wp_remote_request($urlCompleta, [
'method' => 'POST',
'headers' => $cabecalhos,
'body' => json_encode($dadosPost, JSON_UNESCAPED_UNICODE),
'timeout' => 45,
]);
if (is_wp_error($resposta)) {
return [
'status' => 'erro',
'mensagem' => 'falha_na_requisicao',
'dados' => ['erro' => $resposta->get_error_message()],
'timestamp' => (int) $carimboTempo,
];
}
$corpo = wp_remote_retrieve_body($resposta);
return ProcessadorResposta::decodificar($corpo, $idDispositivo, $carimboTempo, $assinatura);
}
private function montarCabecalhos(string $idDispositivo, string $ts, string $assinatura, array $extras = []): array
{
$cabecalhosBase = [
'Accept' => 'application/json',
'Content-Type' => 'application/json;charset=utf-8',
'chaveacesso' => 'x7y8z9',
'idProduto' => 'ABCDEF123',
'idioma' => 'pt',
'codPais' => 'BR-BR',
'canal' => 'WEBFRONTEND',
'versao' => '2.1.0',
'sistema' => 'WEBFRONTEND',
'fusoHorario' => '-3',
'plataforma' => 'WEBFRONTEND',
'codVersao' => '2.1.0',
'tokenDispositivo' => 'WEBFRONTEND',
'sistemaOperacional' => 'WEBFRONTEND',
'deviceId' => $idDispositivo,
'ts' => $ts,
'assinatura' => $assinatura,
];
return array_merge($cabecalhosBase, $extras);
}
private function normalizarCaminho(string $caminho): string
{
$caminho = trim($caminho);
return empty($caminho) ? '/' : '/' . ltrim($caminho, '/');
}
private function resolverIdDispositivo(string $idRaw): string
{
$idRaw = trim($idRaw);
if (!empty($idRaw)) {
return hash('sha256', $idRaw);
}
return hash('sha256', gethostname() . ($_SERVER['SERVER_ADDR'] ?? '0.0.0.0'));
}
}