Introduction
Short-lived access tokens limit exposure; refresh tokens let ShopNest mobile apps get new access tokens without re-login. This advanced lesson implements the full pattern with rotation, revocation, and Identity integration.
After this article you will
- Issue access + refresh token pair on login
- Store refresh tokens hashed in database
- Rotate refresh tokens on each use
- Revoke tokens on logout and security events
- Avoid common JWT security mistakes
Prerequisites
- Article 31 — Authorization — Roles, Policies, Claims
- ShopNest.Web with EF Core and configuration from Module 3
Concept deep-dive
public class RefreshToken
{
public int Id { get; set; }
public string UserId { get; set; } = "";
public string TokenHash { get; set; } = "";
public DateTime ExpiresAt { get; set; }
public DateTime? RevokedAt { get; set; }
public string? ReplacedByTokenHash { get; set; }
public bool IsActive => RevokedAt == null && DateTime.UtcNow < ExpiresAt;
}
// Login response
return Ok(new {
accessToken = GenerateJwt(user, expires: TimeSpan.FromMinutes(15)),
refreshToken = plainRefreshToken, // store hash only
expiresIn = 900
});
// POST /api/auth/refresh
// Validate refresh token hash, revoke old, issue new pair (rotation)
Security: Access token 15 min; refresh 7–30 days; hash refresh tokens (SHA256); bind to device/client ID optional; HTTPS only; never store access token in localStorage if XSS risk — prefer httpOnly cookie for web.
Hands-on — ShopNest Mobile App Backend API
- RefreshToken entity + migration.
- AuthController: login, refresh, logout (revoke), revoke-all.
- Detect reuse of old refresh token — revoke entire family (breach signal).
- Mobile client: intercept 401, call refresh once, retry request.
Common errors & best practices
- Long-lived JWT without refresh — stolen token valid for days.
- Storing refresh token plaintext in DB — hash like passwords.
- Refresh endpoint without rate limiting — brute force vector.
- Same signing key for dev and prod — rotate keys per environment.
Interview questions
Q: Why refresh tokens?
A: Short access token limits damage; refresh allows UX without constant login.
Q: Token rotation?
A: Each refresh invalidates old token and issues new — detects theft if old reused.
Q: Where store refresh token on mobile?
A: Secure storage (Keychain/Keystore), not plain preferences.
Summary
- Access + refresh pattern is industry standard for mobile APIs
- Store hashed refresh tokens; rotate on each refresh
- Revoke on logout and suspicious reuse
- Integrates with Identity user store from Article 29
Previous: Authorization — Roles, Policies, Claims
Next: OAuth2 and External Login
FAQ
Refresh token in cookie for SPA?
Possible with httpOnly + SameSite=Strict — common secure pattern.
JWT blacklist?
Hard with stateless JWT — short expiry + refresh rotation preferred over central blacklist.