feat: generate permission sql for stocktake modules and implement single-device login restriction
This commit is contained in:
@ -1,10 +1,55 @@
|
||||
# app/services/auth_service.py
|
||||
from app.models.system import SysUser, SysRolePermission # <== 引入 SysRolePermission
|
||||
from app.extensions import db
|
||||
from app.extensions import db, redis_client
|
||||
from sqlalchemy import func
|
||||
from flask_jwt_extended import create_access_token, create_refresh_token
|
||||
from flask_jwt_extended import create_access_token, create_refresh_token, get_jwt_identity
|
||||
from flask import current_app
|
||||
from app.utils.constants import UserRole
|
||||
from datetime import timedelta
|
||||
import json
|
||||
|
||||
|
||||
def _store_token_to_redis(user_id, token, token_type='access'):
|
||||
"""
|
||||
将 Token 存储到 Redis,用于单设备登录互踢
|
||||
键名: user_token_{user_id}
|
||||
值: token
|
||||
过期时间: 与 JWT 过期时间一致
|
||||
"""
|
||||
if redis_client is None:
|
||||
current_app.logger.warning("Redis not available, skipping token storage")
|
||||
return False
|
||||
|
||||
try:
|
||||
# 获取 JWT 过期时间配置
|
||||
if token_type == 'access':
|
||||
expires_delta = current_app.config.get('JWT_ACCESS_TOKEN_EXPIRES', timedelta(hours=2))
|
||||
else:
|
||||
expires_delta = current_app.config.get('JWT_REFRESH_TOKEN_EXPIRES', timedelta(days=7))
|
||||
|
||||
# 转换为秒数
|
||||
expires_seconds = int(expires_delta.total_seconds())
|
||||
|
||||
# 存储到 Redis
|
||||
key = f"user_token_{user_id}"
|
||||
redis_client.setex(key, expires_seconds, token)
|
||||
return True
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"Failed to store token to Redis: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def _get_token_from_redis(user_id):
|
||||
"""从 Redis 获取当前有效的 Token"""
|
||||
if redis_client is None:
|
||||
return None
|
||||
try:
|
||||
key = f"user_token_{user_id}"
|
||||
return redis_client.get(key)
|
||||
except Exception as e:
|
||||
current_app.logger.error(f"Failed to get token from Redis: {e}")
|
||||
return None
|
||||
|
||||
|
||||
class AuthService:
|
||||
# 硬编码的超级管理员凭证
|
||||
@ -80,6 +125,11 @@ class AuthService:
|
||||
}
|
||||
)
|
||||
|
||||
# 4. 存储 Token 到 Redis (用于单设备登录互踢)
|
||||
# 使用 str(user_id) 作为 Redis key 的一部分,因为 user_id=0 是超级管理员
|
||||
_store_token_to_redis(str(user_id), access_token, 'access')
|
||||
_store_token_to_redis(str(user_id), refresh_token, 'refresh')
|
||||
|
||||
return {
|
||||
'access_token': access_token,
|
||||
'refresh_token': refresh_token,
|
||||
|
||||
Reference in New Issue
Block a user