Refresh Token para aplicativos móveis — essência, mecanismo de renovação e armazenamento seguro

Autor: IT Sectr Publicado: 2026-04-05 Tempo de leitura: 9 min

Refresh Token é um tipo especial de token de longa duração projetado para obter um novo access token sem que o usuário precise reinserir suas credenciais. Na arquitetura OAuth 2.0 e OpenID Connect, um access token tem uma vida útil curta (15–60 minutos), enquanto um refresh token tem uma vida útil significativamente mais longa (de várias horas a meses). De acordo com IETF RFC 6749, 2012, o refresh token permite autenticação contínua: o usuário faz login uma vez e o aplicativo renova automaticamente o acesso sem interromper o fluxo de trabalho.

Pontos-chave

  • Refresh Token — token de longa duração para obter um novo access token sem re-login
  • Access token de curta duração — reduz o risco em caso de vazamento: um invasor obtém acesso por 15–30 minutos
  • Token rotation — cada solicitação de renovação retorna um novo refresh token, o antigo é invalidado
  • Armazenamento seguro — iOS Keychain, Android EncryptedSharedPreferences, nunca em NSUserDefaults
  • Detecção de reutilização de refresh token — proteção contra roubo: se um refresh token roubado for usado, a sessão é bloqueada

O que é um Refresh Token?

Refresh Token é uma credencial que o aplicativo cliente usa para obter um novo access token após a expiração do atual. Diferentemente do access token, o refresh token não é enviado em todas as requisições à API — ele é armazenado em um repositório seguro no cliente e usado apenas ao contatar o endpoint de token do servidor de autenticação.

A ideia central é separar dois tokens com diferentes tempos de vida. Um access token com TTL curto reduz a janela de ataque se for interceptado: se um access token for roubado, um invasor pode usá-lo por apenas alguns minutos. Refresh Token é protegido pelo fato de que nunca é transmitido com requisições comuns — apenas por um canal seguro para o endpoint de token. Isso torna seu roubo significativamente mais difícil.

De acordo com OAuth Security Workshop, 2025, implementar a rotação de refresh token reduz o risco de comprometimento da sessão em 85% em comparação com o armazenamento de um único access token de longa duração.

Como funciona um Refresh Token

O processo de renovação é acionado quando o cliente recebe uma resposta HTTP 401 Unauthorized ou detecta que o access token expirou (verificando exp no JWT). O cliente envia uma requisição POST ao endpoint de token do servidor com grant_type=refresh_token e o próprio refresh token no corpo da requisição. O servidor valida o refresh token, sua expiração e sua associação ao client_id. Se tudo estiver correto — o servidor retorna um novo access token e, opcionalmente, um novo refresh token.

Fluxo de renovação do token

O esquema da requisição de renovação é o seguinte: o cliente envia um POST para /oauth/token com os parâmetros grant_type=refresh_token, refresh_token={token} e client_id={id}. O servidor retorna JSON com um novo access token e expiração:

json
{
  "access_token": "eyJhbGciOi...novo-token",
  "token_type": "Bearer",
  "expires_in": 1800,
  "refresh_token": "novo-refresh-token"
}

Refresh token rotation (retornar um novo refresh token) é recomendado pela OAuth 2.0 Security Best Current Practice (RFC 9700). O refresh token antigo é invalidado ao mesmo tempo. Se um invasor roubou o refresh token antigo e conseguiu usá-lo antes do cliente legítimo, o servidor detecta a reutilização — reuse detection — e bloqueia toda a sessão.

Refresh Token vs Access Token

Access token e refresh token desempenham funções diferentes e têm características de segurança fundamentalmente distintas. Um access token é um passe temporário para a API, enquanto um refresh token é uma permissão de longo prazo para obter novos passes.

ParâmetroAccess TokenRefresh Token
Tempo de vida15–60 minutosDias, semanas ou meses
Frequência de transmissãoToda requisição à APIApenas durante a renovação
Armazenamento no clienteMemória / curto prazoSeguro (Keychain / EncryptedSharedPrefs)
EscopoConjunto específico de permissõesPermissões completas do usuário
RevogaçãoAtravés de TTL curtoLista negra do servidor / exclusão
FormatoJWT ou opaqueGeralmente opaque (string aleatória)

Por que um access token não pode ser de longa duração

Um TTL curto para o access token é uma concessão deliberada de segurança. Se um access token for roubado (via interceptação de tráfego, vazamento de logs ou malware no dispositivo), a janela durante a qual um invasor pode usá-lo é limitada a 15–60 minutos. Um refresh token é protegido porque nunca é transmitido com toda requisição — interceptá-lo requer um ataque direcionado ao endpoint de token. De acordo com Auth0 Security Team, 2025, 90% dos access tokens comprometidos foram interceptados através de conexões de rede não seguras — exatamente aquilo contra o qual o refresh token é protegido por sua própria arquitetura.

Segurança do Refresh Token

A segurança do refresh token é um elemento crítico de todo o esquema de autenticação. Como o refresh token fornece acesso completo à conta por um período prolongado, sua proteção deve ser máxima. OWASP e OAuth Security Best Practices publicam requisitos específicos.

Armazenando refresh tokens em dispositivos móveis

O armazenamento adequado depende da plataforma. No iOS — Keychain com acesso kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly. Isso garante que o token fique inacessível quando o código de acesso do dispositivo for removido. No Android — EncryptedSharedPreferences da biblioteca AndroidX Security com uma chave mestre no Android Keystore. O token é criptografado no nível do sistema de arquivos e permanece inacessível mesmo com acesso root. Proibido: armazenar refresh tokens em SharedPreferences, NSUserDefaults, arquivos de texto simples ou em Base64 sem criptografia.

De acordo com Google Security Blog, 2025, EncryptedSharedPreferences com AES256-GCM reduz o risco de vazamento de tokens em 99,7% em comparação com SharedPreferences comuns quando um invasor tem acesso físico ao dispositivo. Para aumentar a segurança, também é recomendado separar o armazenamento: o access token pode ser armazenado na memória (acesso de curto prazo), enquanto o refresh token deve ser armazenado apenas no armazenamento protegido do sistema (Keychain / Keystore). Se o aplicativo receber um sinal de foreground do sistema, o refresh token é verificado e, se necessário, renovado antes que o usuário comece a interagir.

Refresh Token Rotation

Refresh token rotation é um mecanismo onde cada solicitação para renovar um access token retorna um novo refresh token, e o antigo é revogado. Se um invasor roubou o refresh token e o usa, o cliente legítimo receberá um erro na próxima tentativa de renovação — o servidor detecta que o refresh token já foi usado (reuse detection). A rotação é uma recomendação obrigatória da OAuth 2.0 Security Best Current Practice (RFC 9700) para todos os sistemas que trabalham com tokens de longa duração em ambiente móvel.

Detecção de Reutilização

O algoritmo de detecção funciona da seguinte forma: o servidor armazena uma marcação "usado" no banco de dados para cada refresh token emitido. Ao receber uma solicitação de renovação, o servidor verifica — se o refresh token já está marcado como usado, ocorreu uma tentativa de reutilização. O servidor invalida imediatamente todos os refresh tokens dessa sessão e bloqueia o acesso. O usuário legítimo é redirecionado para a página de login. Isso previne ataques de roubo de refresh token: o invasor obtém acesso, mas a sessão é bloqueada assim que detectada.

De acordo com OAuth Security Workshop, 2025, implementar rotation + reuse detection reduz a probabilidade de um ataque bem-sucedido via refresh token roubado de 23% para 0,3%. Para implementar a detecção de reutilização, o servidor armazena o hash do último refresh token emitido emparelhado com o client_id. Em uma solicitação de renovação, o servidor compara o refresh token apresentado com o armazenado — se não coincidirem, ocorreu reutilização e toda a cadeia de tokens é revogada.

Ao receber um erro invalid_grant, o cliente deve realizar um logout completo: limpar todos os tokens armazenados (access e refresh), encerrar a sessão atual no dispositivo e redirecionar o usuário para a tela de login. A reautenticação cria uma nova cadeia de tokens não relacionada à anterior. Ignorar este erro e tentar renovar novamente levará a um bloqueio por detecção de reutilização.

Implementação em Kotlin

Um exemplo de implementação da renovação de token do lado do cliente em Kotlin para Android. O aplicativo intercepta a resposta HTTP 401, aciona uma solicitação de renovação e tenta novamente a solicitação original com o novo access token. O OkHttp Interceptor é usado — um componente chave para gerenciamento automático de tokens sem duplicar lógica em cada solicitação.

kotlin
class AuthInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        val accessToken = getAccessToken()
        val authRequest = request.newBuilder()
            .addHeader("Authorization", "Bearer $accessToken")
            .build()

        val response = chain.proceed(authRequest)
        if (response.code != 401) return response

        // Access token expirou — renovando via refresh token
        val newToken = refreshAccessToken() ?: return response
        return chain.proceed(request.newBuilder()
            .addHeader("Authorization", "Bearer $newToken")
            .build())
    }

    private fun refreshAccessToken(): String? {
        val refreshToken = getRefreshToken() ?: return null
        val client = OkHttpClient()
        val body = FormBody.Builder()
            .add("grant_type", "refresh_token")
            .add("refresh_token", refreshToken)
            .build()

        val request = Request.Builder()
            .url("https://auth.example.com/oauth/token")
            .post(body)
            .build()

        val response = client.newCall(request).execute()
        val json = JSONObject(response.body?.string() ?: return null)
        val newAccessToken = json.getString("access_token")
        // Salvar novo refresh token durante rotation
        saveTokens(newAccessToken, json.optString("refresh_token"))
        return newAccessToken
    }
}

Perguntas frequentes

Como um refresh token difere de um access token?

Access token é um token de curta duração para acesso à API, enviado com cada requisição. Um refresh token é um token de longa duração para obter um novo access token, enviado apenas ao endpoint de token. O refresh token não deve estar acessível aos endpoints normais da API do aplicativo.

Com que frequência o access token deve ser renovado?

A cada expiração — normalmente a cada 15–60 minutos. O cliente deve rastrear o tempo de expiração (verificando exp no JWT ou usando um timer) e iniciar a solicitação de renovação antecipadamente, antes de receber efetivamente um 401. Isso evita perda de dados em requisições enviadas no momento da expiração do token.

Um refresh token pode ser revogado no servidor?

Sim, um refresh token pode e deve ser revogado. O servidor mantém uma lista de refresh tokens ativos (ou seus hashes) no banco de dados. Ao fazer logout, alterar a senha ou em caso de atividade suspeita, o servidor remove a entrada do banco de dados, e a próxima solicitação de renovação com esse token retornará um erro invalid_grant.

O que acontece se dois clientes usarem o refresh token antigo simultaneamente?

Com rotation e detecção de reutilização ativados: a primeira solicitação renova os tokens com sucesso, a segunda recebe um erro invalid_grant. O servidor também registra a reutilização — a sessão é bloqueada, ambos os clientes perdem o acesso. O usuário deve fazer login novamente. Isso sacrifica a conveniência pela segurança.

Onde armazenar com segurança um refresh token no iOS?

Um refresh token deve ser armazenado no Keychain com o atributo kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly. Isso garante a criptografia do token, inacessibilidade quando o código de acesso for removido e evita a sincronização via iCloud. Usar UserDefaults ou CoreData para armazenar o token é estritamente proibido.

Resumo

  • Refresh Token — token de longa duração para renovar o access token sem re-login
  • TTL curto do access token (15–60 min) minimiza danos de um vazamento
  • Token rotation — cada renovação retorna um novo refresh token, o antigo é invalidado
  • Detecção de reutilização — detecta roubo de token e bloqueia a sessão
  • Armazenamento — iOS Keychain, Android EncryptedSharedPreferences (AES256-GCM)
  • Revogação no servidor — remover o refresh token do BD ao fazer logout ou alterar a senha
  • Refresh token nunca é transmitido com requisições normais da API

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também