リフレッシュトークンと有効期限
安全なトークン更新を実装します。
「リフレッシュトークンと有効期限」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。
有効期限の問題
有効期間の短いアクセストークンは安全ですが、不便でもあります。15分ごとにユーザーへログインを求めるのは、優れた UX とはいえません。
解決策はリフレッシュトークンです。これは、パスワードを再入力せずに新しいアクセストークンを取得するための、別の有効期間の長い認証情報です。
// access token: 15 minutes
// refresh token: 7-30 daysリフレッシュトークンとは
リフレッシュトークンは通常、不透明なランダム文字列(JWT ではありません)です。有効期間が長いため、失効できるようサーバー側に保存する必要があります。
生成には、暗号学的に安全な乱数生成器を使用してください。
public static string GenerateRefreshToken()
{
var bytes = new byte[64];
using var rng = RandomNumberGenerator.Create();
rng.GetBytes(bytes);
return Convert.ToBase64String(bytes);
}リフレッシュトークンの保存
各リフレッシュトークンを、所有者、有効期限、失効フラグとともに永続化します。これにより、ログアウト時や盗難時に無効化できます。
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; }
}ログイン時の両方のトークンの発行
ログインが成功したら、有効期間の短いアクセストークンと新しいリフレッシュトークンを返します。リフレッシュトークンはデータベースに保存します。
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 });リフレッシュエンドポイント
専用の /refresh エンドポイントでリフレッシュトークンを受け取り、有効であればまったく新しいアクセストークンを発行します。
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 });
});リフレッシュトークンのローテーション
ローテーションによってフローを強化できます。リフレッシュトークンが使われるたびにそれを失効させ、新しいトークンを発行します。盗まれたトークンがすでに使用済みであれば、そのトークンは役に立たなくなります。
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();トークンの再利用の検出
ローテーションを使うと盗難を検出できます。すでに失効したトークンが再び提示された場合は、侵害が発生したと判断し、ユーザーのトークンファミリー全体を失効させます。
if (stored.IsRevoked)
{
// This token was already used - likely stolen.
await RevokeAllUserTokens(stored.UserId, db);
return Results.Unauthorized();
}ログアウトと失効
ログアウトでは、現在のリフレッシュトークンを失効させるだけです。アクセストークンは数分以内に自然に期限切れになります。
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();クライアントでのトークンの保存場所
ブラウザーでは、JavaScript から読み取れないようHttpOnly、Secure Cookieにリフレッシュトークンを保存するのが最も安全なパターンです。これにより、XSS による盗難を軽減できます。
有効期間の短いアクセストークンはメモリに保持できます。
Response.Cookies.Append("refresh", refresh.Token, new CookieOptions
{
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.Strict,
Expires = refresh.ExpiresAt
});期限切れトークンのクリーンアップ
リフレッシュトークンは蓄積されます。定期的なバックグラウンドジョブ(例: ホステッドサービス)を実行して、期限切れまたは失効したレコードを削除します。
await db.RefreshTokens
.Where(r => r.ExpiresAt < DateTime.UtcNow || r.IsRevoked)
.ExecuteDeleteAsync();有効期間の選択
セキュリティと利便性のバランスを取ります。
- アクセストークン: 5~15分。漏えいしたトークンの影響を抑えます。
- リフレッシュトークン: 機密性に応じて、数時間から数週間。
- 1日を超える場合は、ローテーションを使用します。
AccessTokenLifetime = TimeSpan.FromMinutes(15);
RefreshTokenLifetime = TimeSpan.FromDays(7);確認問題
リフレッシュフローについての理解度を確認します。
まとめ
リフレッシュトークンフローを実装しました。
- 有効期間の短いアクセストークンと、長く不透明でサーバーに保存するリフレッシュトークンを発行します。
/refreshエンドポイントで、有効なリフレッシュトークンを新しいアクセストークンと交換します。- ローテーションと再利用の検出により、盗難への耐性を高めます。
- リフレッシュトークンを HttpOnly Cookie に保存し、期限切れのレコードをクリーンアップします。
これで JWT 認証コースは完了です。
よくある質問
「リフレッシュトークンと有効期限」レッスンは無料ですか?
はい。「リフレッシュトークンと有効期限」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。
「リフレッシュトークンと有効期限」で何を学びますか?
安全なトークン更新を実装します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
C# Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「リフレッシュトークンと有効期限」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このC# Academyレッスンでコードを書いて実行できますか?
はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- JWTの構造とクレーム
- JWT Bearer認証の設定
- トークンの発行
- リフレッシュトークンと有効期限