Melhorando a segurança para chamadas de API com dados sensíveis no Flutter com o Cloud Functions

Thiago Fontes
Kobe
Published in
3 min readDec 26, 2022
Photo by Markus Spiske on Unsplash

Muitas vezes nos deparamos com chamadas de api que precisam de dados sensíveis para funcionar. No entanto, deixar esses dados dentro do aplicativo pode ser muito problemático do ponto de vista de seguraça. O ideal seria que o aplicativo nunca tivesse acesso a esses dados. Mas como fazer isso?

Neste artigo vamos usar o firebase de middleware para o login com credenciais fixas, à título de exemplo. A primeira abordagem pensando em usar firebase pode ser salvar os dados em uma das formas de armazenamento para que o app tenha acesso a eles. Porém, fazendo isso, entraríamos no mesmo problema onde esses dados poderiam vazar por estarem indo até o aplicativo.

A abordagem sugerida, portanto, é fazer a chamada usando uma cloud function no Firebase. Este é um recurso do plano pago, mas você pode testar usando o pacote de emuladores locais do Firebase. Para configurar você pode seguir esse tutorial: Executar funções localmente.

Emulador do cloud functions rodando no terminal

Assumindo que você consiga criar functions no firebase ou que tenha seguido o tutorial para rodar uma function usando a suite de emuladores, vamos ao código que fará a request na cloud function:

'use strict';const functions = require('firebase-functions');
const fetch = require('node-fetch');
const LOGIN_URL = 'https://example.com/login';exports.login = functions.https.onCall(async (req, res) => {
const data = JSON.stringify({user: 'meu_user', pass: 'pass321'}) const response = await fetch(LOGIN_URL, {
method: 'post',
body: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded','x- requested-with':'XMLHttpRequest'}
});if (!response.ok) {
const error = await response.text();
throw new Error(`HTTP Error: ${error}`);
}const body = await response.text();
console.log(`BODY: ${body}`);return {
body: body,
};
});

O código acima fará a chamada usando o usuário e senha que não pode ficar exposto e retornará o resultado ao final. Este é apenas um exemplo, que também poderia ser aplicado a chaves de API ou qualquer outro dado que, por motivos de seguraça, não pudesse ficar no frontend.

Importante: Ao utilizar o emulador do Firebase deve-se lembrar de apontar o serviço de Cloud Functions para o “localhost” com a porta apropriada:

FirebaseFunctions.instance.useFunctionsEmulator('localhost', 5001);

No aplicativo a chamada seria feita da seguinte forma:

Future<void> call() async {
HttpsCallable callable =
FirebaseFunctions.instance.httpsCallable('login'); final resp = await callable.call();

log("result: ${resp.data}");
}

Resposta do login com sucesso no log do aplicativo

Como pode ser visto, agora a forma que a chamada é feita e os argumentos da API são transparentes para o aplicativo. Assim, de maneira simples melhoramos a segurança do app. Como boas práticas, é recomendado usar o secret manager para salvar os dados e, assim, diminuir ainda mais a exposição: https://cloud.google.com/functions/docs/configuring/secrets

Espero que as dicas tenham ajudado você a potencializar a segurança das suas aplicações.

--

--