feat(api/auth): switch-to-stateful-authentication (#5438)

This commit is contained in:
-LAN-
2024-06-21 12:39:07 +08:00
committed by GitHub
parent 26b6fd2236
commit 1336b844fd
8 changed files with 89 additions and 43 deletions

View File

@@ -13,7 +13,6 @@ from werkzeug.exceptions import Unauthorized
from constants.languages import language_timezone_mapping, languages
from events.tenant_event import tenant_was_created
from extensions.ext_redis import redis_client
from libs.helper import get_remote_ip
from libs.passport import PassportService
from libs.password import compare_password, hash_password, valid_password
from libs.rsa import generate_key_pair
@@ -67,10 +66,10 @@ class AccountService:
@staticmethod
def get_account_jwt_token(account):
def get_account_jwt_token(account, *, exp: timedelta = timedelta(days=30)):
payload = {
"user_id": account.id,
"exp": datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(days=30),
"exp": datetime.now(timezone.utc).replace(tzinfo=None) + exp,
"iss": current_app.config['EDITION'],
"sub": 'Console API Passport',
}
@@ -195,14 +194,35 @@ class AccountService:
return account
@staticmethod
def update_last_login(account: Account, request) -> None:
def update_last_login(account: Account, *, ip_address: str) -> None:
"""Update last login time and ip"""
account.last_login_at = datetime.now(timezone.utc).replace(tzinfo=None)
account.last_login_ip = get_remote_ip(request)
account.last_login_ip = ip_address
db.session.add(account)
db.session.commit()
logging.info(f'Account {account.id} logged in successfully.')
@staticmethod
def login(account: Account, *, ip_address: Optional[str] = None):
if ip_address:
AccountService.update_last_login(account, ip_address=ip_address)
exp = timedelta(days=30)
token = AccountService.get_account_jwt_token(account, exp=exp)
redis_client.set(_get_login_cache_key(account_id=account.id, token=token), '1', ex=int(exp.total_seconds()))
return token
@staticmethod
def logout(*, account: Account, token: str):
redis_client.delete(_get_login_cache_key(account_id=account.id, token=token))
@staticmethod
def load_logged_in_account(*, account_id: str, token: str):
if not redis_client.get(_get_login_cache_key(account_id=account_id, token=token)):
return None
return AccountService.load_user(account_id)
def _get_login_cache_key(*, account_id: str, token: str):
return f"account_login:{account_id}:{token}"
class TenantService: