feat(auth): refresh tokens + remember me
Backend: add refresh JWT (30d, token_type claim), POST /auth/refresh endpoint (rotates token pair), remember_me on login, JWT_REFRESH_EXPIRY_DAYS env var. Extractors now reject refresh tokens on protected routes. Frontend: sessionStorage for non-remembered sessions, localStorage + refresh token for remembered sessions. Transparent 401 recovery in api.ts (retry once after refresh). Remember me checkbox on login page with security note when checked.
This commit is contained in:
@@ -15,6 +15,15 @@ pub struct LoginRequest {
|
||||
pub email: Email,
|
||||
/// Password is validated on deserialization (min 8 chars)
|
||||
pub password: Password,
|
||||
/// When true, a refresh token is also issued for persistent sessions
|
||||
#[serde(default)]
|
||||
pub remember_me: bool,
|
||||
}
|
||||
|
||||
/// Refresh token request
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct RefreshRequest {
|
||||
pub refresh_token: String,
|
||||
}
|
||||
|
||||
/// Register request with validated email and password newtypes
|
||||
@@ -41,6 +50,9 @@ pub struct TokenResponse {
|
||||
pub access_token: String,
|
||||
pub token_type: String,
|
||||
pub expires_in: u64,
|
||||
/// Only present when remember_me was true at login, or on token refresh
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub refresh_token: Option<String>,
|
||||
}
|
||||
|
||||
/// Per-provider info returned by `GET /config`.
|
||||
|
||||
Reference in New Issue
Block a user