mirror of
https://github.com/hansjone/netx.git
synced 2026-10-09 13:00:44 +08:00
Harden auth with revocable sessions, cookies, and single-login default.
Issue short-lived access JWTs backed by AuthSession rows, HttpOnly cookies with refresh rotation, idle timeout, session management UI, WebCRT ownership caps, and optional Redis login rate limits; new logins revoke other sessions by default. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
ba33ab5c4f
commit
20c2fcd496
34 changed files with 1462 additions and 149 deletions
|
|
@ -61,3 +61,21 @@ class ApiToken(Base):
|
|||
expires_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, index=True)
|
||||
last_used_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
||||
revoked_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
||||
|
||||
|
||||
class AuthSession(Base):
|
||||
"""Server-side JWT session (jti). Logout / password change can revoke without waiting for exp."""
|
||||
|
||||
__tablename__ = "auth_session"
|
||||
|
||||
id: Mapped[str] = mapped_column(String(64), primary_key=True) # JWT jti
|
||||
user_id: Mapped[str] = mapped_column(String(64), index=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=utcnow_naive)
|
||||
expires_at: Mapped[datetime] = mapped_column(DateTime, index=True)
|
||||
revoked_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, index=True)
|
||||
client_ip: Mapped[str] = mapped_column(String(128), default="")
|
||||
user_agent: Mapped[str] = mapped_column(String(512), default="")
|
||||
last_seen_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
||||
# Opaque refresh token (hashed); longer-lived than access JWT.
|
||||
refresh_token_hash: Mapped[str] = mapped_column(String(128), default="", index=True)
|
||||
refresh_expires_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True, index=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue