0Pricing
C# Academy · Aula

Tokens de atualização e expiração

Implemente a renovação segura de tokens.

Tokens de atualização e expiração é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.

O problema da expiração

Tokens de acesso de curta duração são seguros, mas inconvenientes: obrigar os usuários a fazer login a cada 15 minutos proporciona uma experiência ruim.

A solução é um token de atualização; uma credencial separada, com maior duração, usada para obter novos tokens de acesso sem digitar a senha novamente.

// access token: 15 minutes
// refresh token: 7-30 days

O que é um token de atualização

Um token de atualização geralmente é uma cadeia aleatória opaca (não um JWT). Como tem longa duração, ele precisa ser armazenado no servidor para que possa ser revogado.

Gere-o com um RNG criptograficamente seguro.

public static string GenerateRefreshToken()
{
    var bytes = new byte[64];
    using var rng = RandomNumberGenerator.Create();
    rng.GetBytes(bytes);
    return Convert.ToBase64String(bytes);
}

Armazenando tokens de atualização

Persista cada token de atualização com seu proprietário, sua expiração e um indicador de revogação. Isso permite invalidá-lo em caso de logout ou roubo.

public class RefreshToken
{
    public int Id { get; set; }
    public string Token { get; set; } = default!;
    public int UserId { get; set; }
    public DateTime ExpiresAt { get; set; }
    public bool IsRevoked { get; set; }
}

Emitindo os dois tokens no login

Após um login bem-sucedido, devolva o token de acesso de curta duração e um novo token de atualização. Salve o token de atualização no banco de dados.

var access = tokenService.CreateAccessToken(user);
var refresh = new RefreshToken
{
    Token = TokenService.GenerateRefreshToken(),
    UserId = user.Id,
    ExpiresAt = DateTime.UtcNow.AddDays(7)
};
db.RefreshTokens.Add(refresh);
await db.SaveChangesAsync();
return Results.Ok(new { access, refresh = refresh.Token });

O ponto de acesso de atualização

Um ponto de acesso /refresh dedicado aceita um token de atualização e, se ele for válido, emite um token de acesso totalmente novo.

app.MapPost("/refresh", async (RefreshDto dto, AppDb db, TokenService tokens) =>
{
    var stored = await db.RefreshTokens
        .SingleOrDefaultAsync(r => r.Token == dto.RefreshToken);

    if (stored is null || stored.IsRevoked ||
        stored.ExpiresAt < DateTime.UtcNow)
        return Results.Unauthorized();

    var user = await db.Users.FindAsync(stored.UserId);
    var access = tokens.CreateAccessToken(user!);
    return Results.Ok(new { access });
});

Rotação de tokens de atualização

A rotação reforça o fluxo: sempre que um token de atualização for usado, revogue-o e emita um novo. Assim, um token roubado que já tenha sido usado se torna inútil.

stored.IsRevoked = true;            // burn the old one
var next = new RefreshToken
{
    Token = TokenService.GenerateRefreshToken(),
    UserId = stored.UserId,
    ExpiresAt = DateTime.UtcNow.AddDays(7)
};
db.RefreshTokens.Add(next);
await db.SaveChangesAsync();

Detectando a reutilização de tokens

Com a rotação, você pode detectar um roubo: se um token que já foi revogado for apresentado novamente, trate isso como um comprometimento e revogue toda a família de tokens do usuário.

if (stored.IsRevoked)
{
    // This token was already used - likely stolen.
    await RevokeAllUserTokens(stored.UserId, db);
    return Results.Unauthorized();
}

Encerramento da sessão e revogação

Encerrar a sessão simplesmente revoga o token de atualização atual. O token de acesso expirará por conta própria em poucos minutos.

app.MapPost("/logout", async (RefreshDto dto, AppDb db) =>
{
    var stored = await db.RefreshTokens
        .SingleOrDefaultAsync(r => r.Token == dto.RefreshToken);
    if (stored is not null) stored.IsRevoked = true;
    await db.SaveChangesAsync();
    return Results.Ok();
}).RequireAuthorization();

Onde armazenar tokens no cliente

Para navegadores, o padrão mais seguro armazena o token de atualização em um cookie HttpOnly e Secure, para que o JavaScript não possa lê-lo, reduzindo o risco de roubo por XSS.

O token de acesso de curta duração pode ser mantido na memória.

Response.Cookies.Append("refresh", refresh.Token, new CookieOptions
{
    HttpOnly = true,
    Secure = true,
    SameSite = SameSiteMode.Strict,
    Expires = refresh.ExpiresAt
});

Limpando tokens expirados

Os tokens de atualização se acumulam. Execute um trabalho periódico em segundo plano (por exemplo, um serviço hospedado) para excluir registros expirados ou revogados.

await db.RefreshTokens
    .Where(r => r.ExpiresAt < DateTime.UtcNow || r.IsRevoked)
    .ExecuteDeleteAsync();

Escolhendo durações

Equilibre segurança e conveniência:

  • Token de acesso: 5 a 15 minutos; limita a exposição de um token vazado.
  • Token de atualização: de horas a semanas, dependendo da sensibilidade.
  • Use rotação para qualquer duração superior a um dia.
AccessTokenLifetime  = TimeSpan.FromMinutes(15);
RefreshTokenLifetime = TimeSpan.FromDays(7);

Verificação rápida

Teste sua compreensão do fluxo de atualização.

Recapitulação

Você implementou o fluxo de tokens de atualização:

  • Emita um token de acesso curto junto com um token de atualização longo, opaco e armazenado no servidor.
  • Um ponto de acesso /refresh troca um token de atualização válido por um novo token de acesso.
  • A rotação e a detecção de reutilização reforçam a proteção contra roubo.
  • Armazene os tokens de atualização em cookies HttpOnly e limpe os registros expirados.

Isso conclui o curso de autenticação JWT.

Perguntas Frequentes

A aula “Tokens de atualização e expiração” é grátis?

Sim — o texto completo de “Tokens de atualização e expiração” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.

O que vou aprender em “Tokens de atualização e expiração”?

Implemente a renovação segura de tokens. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar C# Academy?

Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Tokens de atualização e expiração”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de C# Academy?

Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Estrutura e declarações de JWT
  2. Configurando a autenticação JWT Bearer
  3. Emitindo tokens
  4. Tokens de atualização e expiração
← Voltar para C# Academy