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 daysO 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
/refreshtroca 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
- Estrutura e declarações de JWT
- Configurando a autenticação JWT Bearer
- Emitindo tokens
- Tokens de atualização e expiração