mirror of
https://github.com/Such-Software/smirk-backend-core.git
synced 2026-10-22 01:38:43 +02:00
auth: make access tokens revocable
verify_access_token was a pure signature + expiry check, so an access token could not be revoked. Sign-out and logout revoked the DB session row, and an erasure request revoked all of them, but the bearer token kept working for the rest of its 24h life on every authenticated route. The refresh token has always carried a sid for exactly this; the access token, which actually guards the API, did not. Adds sid to AccessTokenClaims and checks it against the sessions table on each authenticated request (one indexed primary-key lookup). sid is Option so tokens minted before this deploy still verify rather than logging every user out mid-session; they simply remain unrevocable until they expire, which is the pre-existing behaviour.
This commit is contained in:
@@ -36,6 +36,16 @@ pub async fn extract_user_id_from_token(
|
||||
) -> Result<Uuid, AppError> {
|
||||
let token = bearer_token(headers)?;
|
||||
let info = state.sessions.verify_access_token(token)?;
|
||||
// Signature + expiry alone is not enough: it made access tokens
|
||||
// unrevocable, so sign-out and even a completed erasure request left the
|
||||
// bearer token working for the rest of its 24h life. Tokens minted before
|
||||
// `sid` shipped carry no session and keep the old behaviour until they
|
||||
// expire, rather than logging everyone out on deploy.
|
||||
if let Some(sid) = info.session_id {
|
||||
if !state.db.is_session_live(sid).await? {
|
||||
return Err(AppError::AuthError("Invalid or expired token".into()));
|
||||
}
|
||||
}
|
||||
Ok(info.user_id)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user