05/17 enhance codes
This commit is contained in:
@@ -129,18 +129,29 @@ def blacklist_token(token: str, token_type: str) -> None:
|
||||
if not jti:
|
||||
return
|
||||
exp = payload.get('exp')
|
||||
expires_at = datetime.fromtimestamp(exp, tz=timezone.utc).replace(tzinfo=None) if exp else datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(days=7)
|
||||
expires_at = (
|
||||
datetime.fromtimestamp(exp, tz=timezone.utc).replace(tzinfo=None)
|
||||
if exp
|
||||
else datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(days=7)
|
||||
)
|
||||
from app.models.token_blacklist import TokenBlacklist
|
||||
from app import db
|
||||
# Avoid duplicate if already blacklisted
|
||||
if not TokenBlacklist.query.filter_by(jti=jti).first():
|
||||
entry = TokenBlacklist(
|
||||
jti=jti,
|
||||
user_id=int(payload.get('sub', 0)),
|
||||
expires_at=expires_at,
|
||||
)
|
||||
db.session.add(entry)
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
# INSERT directly — no SELECT-before-INSERT race.
|
||||
# Two concurrent logouts of the same token would both try to insert,
|
||||
# but the UNIQUE constraint on jti makes exactly one succeed.
|
||||
# We catch IntegrityError and roll back gracefully; the token is
|
||||
# already blacklisted so the outcome is correct either way.
|
||||
entry = TokenBlacklist(
|
||||
jti=jti,
|
||||
user_id=int(payload.get('sub', 0)),
|
||||
expires_at=expires_at,
|
||||
)
|
||||
db.session.add(entry)
|
||||
try:
|
||||
db.session.commit()
|
||||
except IntegrityError:
|
||||
db.session.rollback() # already blacklisted — safe to ignore
|
||||
# Cleanup is handled by the APScheduler background job in create_app(),
|
||||
# not here — keeps the logout/refresh hot path free of extra DB writes.
|
||||
except Exception:
|
||||
|
||||
Reference in New Issue
Block a user