Botão copiar no app: o que pode ir para a área de transferência e por quanto tempo
Decida o que seu app MAUI pode copiar, marque conteúdo sensível no Android, limpe a área de transferência depois de um prazo e ofereça alternativas melhores para senha e código.
O painel do app mostra a chave de API recém-criada com um botão "copiar". O desenvolvedor copia, cola no servidor e segue o dia. Duas horas depois, cola um link no grupo da empresa e percebe que o teclado do celular sugeriu, como primeira opção, a chave. Ela continuava lá, no histórico do teclado, e poderia ter ido para o grupo inteiro. A resposta curta: tudo que você copia fica disponível para outros apps, para o histórico do teclado e, às vezes, para outros aparelhos da mesma conta. Copie à vontade o que é público; para segredo, marque como sensível, limpe depois de um prazo curto e, sempre que der, ofereça um caminho que não passe pela área de transferência.
O exemplo é um app .NET MAUI de um SaaS com três botões de copiar: o link de convite da equipe, o número do pedido e a chave de API. Cada um pede um tratamento diferente. Este post trata de copiar; o caminho inverso, ler o que a pessoa colou, está em colar da área de transferência com cuidado.
Por que copiar é mais público do que parece
A área de transferência é um espaço compartilhado do sistema. O que entra nela fica até ser substituído, e vários componentes podem ver:
- Teclados com histórico. Teclados populares no Android guardam os últimos itens copiados e os oferecem como sugestão em qualquer campo.
- Histórico do sistema. No Windows, o histórico da área de transferência (Win+V) guarda vários itens e pode sincronizar entre computadores da mesma conta, se a pessoa ativou.
- Sincronização entre aparelhos. Nos aparelhos Apple, a área de transferência universal pode levar o conteúdo copiado no iPhone para o Mac próximo.
- Outros apps. As versões recentes de Android e iOS restringiram a leitura em segundo plano e mostram aviso quando um app lê, mas o app em primeiro plano ainda consegue ler o que você deixou lá.
No Android 13 em diante, o sistema também mostra uma prévia visual do texto copiado no canto da tela. Útil para link, péssimo para chave de API numa reunião com tela compartilhada.
Como decidir o que pode ser copiado
- Público ou sem poder de autenticar: link de convite com expiração, número de pedido, endereço, código de rastreio. Copie normalmente e mostre "copiado".
- Sensível, mas que a pessoa precisa transportar: chave de API exibida uma vez, código de recuperação. Copie marcado como sensível e limpe depois de um prazo curto, avisando o prazo na tela.
- Segredo que tem caminho melhor: senha e código de uso único. Senha deve ser preenchida pelo gerenciador de senhas; código de SMS pode ser preenchido pelo próprio sistema com o tipo de campo certo. Não ofereça botão de copiar.
- Nunca: token de sessão, documento completo de cliente, dados de cartão. Não há motivo de interface que justifique.
Como copiar no .NET MAUI
Para o que é público, a API multiplataforma resolve:
async Task CopiarConviteAsync(string link)
{
await Clipboard.Default.SetTextAsync(link);
await Toast.Make("Link copiado").Show(); // CommunityToolkit.Maui
}
Se não usa o CommunityToolkit, troque o toast por um rótulo que aparece por alguns segundos. O importante é o retorno visual: sem ele, a pessoa aperta o botão três vezes.
Para a chave de API, o Android oferece uma marcação de conteúdo sensível, documentada pelo próprio Android: a prévia do sistema mostra pontos no lugar do texto. Em MAUI, isso exige código da plataforma:
#if ANDROID
using Android.Content;
using Android.OS;
#endif
public static class CopiaSensivel
{
public static async Task CopiarAsync(string valor, TimeSpan validade)
{
#if ANDROID
var cm = (ClipboardManager)Platform.AppContext
.GetSystemService(Context.ClipboardService)!;
var clip = ClipData.NewPlainText("chave", valor);
var extras = new PersistableBundle();
extras.PutBoolean("android.content.extra.IS_SENSITIVE", true);
clip.Description!.Extras = extras;
cm.PrimaryClip = clip;
#else
await Clipboard.Default.SetTextAsync(valor);
#endif
_ = LimparDepoisAsync(validade);
}
static async Task LimparDepoisAsync(TimeSpan validade)
{
await Task.Delay(validade);
await MainThread.InvokeOnMainThreadAsync(
() => Clipboard.Default.SetTextAsync(null));
}
}
Chame com CopiaSensivel.CopiarAsync(chave, TimeSpan.FromSeconds(60)) e mostre na tela: "Chave copiada. A área de transferência será limpa em 60 segundos." A limpeza tem limites: se o app for encerrado antes do prazo, ela não acontece, e o histórico do teclado pode já ter guardado o valor. Por isso ela reduz o risco, não o elimina.
No iOS, a API nativa UIPasteboard aceita opções de data de expiração e de conteúdo só local (sem ir para outros aparelhos). Se o seu app tem segredo copiável no iOS, vale escrever o trecho de plataforma com essas opções, seguindo a documentação da Apple.
A alternativa melhor: não passar pela área de transferência
A chave de API que só aparece uma vez pode ter um botão "baixar arquivo .env" ou um comando pronto para a CLI do produto, com a chave lida de um fluxo autenticado. O login pode usar o gerenciador de senhas do sistema, se os campos tiverem o tipo certo. Na web, o mesmo raciocínio vale para navigator.clipboard.writeText, que só funciona em página segura e a partir de um gesto do usuário. E se o segredo for uma senha de banco ou um token de bot, o lugar dele é o servidor, como em log sem senha e token do bot fora do Git.
Erros comuns
- Botão copiar ao lado da senha "para facilitar". A senha vai para o histórico do teclado e aparece como sugestão em qualquer app.
- Copiar token de sessão para "suporte". Quem recebe o texto entra na conta da pessoa sem senha.
- Sem aviso de "copiado". A pessoa repete o toque, cola o valor antigo ou acha que nada aconteceu.
- Limpar sem avisar. A pessoa vai colar no minuto seguinte, não encontra nada e conclui que o app falhou.
- Confiar só na limpeza. Teclados e históricos do sistema já podem ter guardado o valor antes do prazo.
- Copiar dado pessoal completo. CPF inteiro ou endereço com nome viajam para outros aparelhos da mesma conta sem a pessoa perceber.
Checklist
- Lista dos botões de copiar do app, cada um classificado como público, sensível ou proibido.
- Retorno visual em toda cópia.
- Conteúdo sensível marcado no Android 13 ou superior.
- Limpeza com prazo curto e aviso do prazo na tela.
- Nenhum botão de copiar em senha, token de sessão ou cartão.
- Campos de senha e código com o tipo certo para o preenchimento automático.
- Teste num aparelho real com teclado que guarda histórico.
Copie a chave de teste no seu app e abra o teclado em outro aplicativo. Ela aparece como sugestão de colagem? Então qualquer campo daquele aparelho pode recebê-la com um toque. E a pergunta para revisar o app inteiro: algum botão de copiar coloca na área de transferência algo que autenticaria a pessoa?
Referência: https://learn.microsoft.com/dotnet/maui/platform-integration/data/clipboard