调整文档路径
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
"""鼎捷云 IAM token 鉴权服务
|
||||
|
||||
通过调用 IAM `/api/iam/v2/identity/token/analyze` 校验请求头中的
|
||||
digi-middleware-auth-user / digi-middleware-auth-app,解析出用户信息。
|
||||
|
||||
进程内 LRU 缓存(userToken -> userInfo),TTL 由 IAM_CACHE_TTL 控制,
|
||||
减少对 IAM 的重复调用。
|
||||
"""
|
||||
|
||||
import time
|
||||
|
||||
import httpx
|
||||
|
||||
from .config import settings
|
||||
|
||||
# httpx 异步客户端(进程级单例,复用连接池)
|
||||
_http_client: httpx.AsyncClient | None = None
|
||||
|
||||
# 缓存:userToken -> (user_info, fetched_at)
|
||||
_cache: dict[str, tuple[dict | None, float]] = {}
|
||||
|
||||
|
||||
def _get_http_client() -> httpx.AsyncClient:
|
||||
global _http_client
|
||||
if _http_client is None:
|
||||
_http_client = httpx.AsyncClient(timeout=5.0)
|
||||
return _http_client
|
||||
|
||||
|
||||
async def close_iam_client() -> None:
|
||||
"""关闭 httpx 客户端(进程退出时调用)。"""
|
||||
global _http_client
|
||||
if _http_client is not None:
|
||||
await _http_client.aclose()
|
||||
_http_client = None
|
||||
|
||||
|
||||
async def analyze_token(user_token: str, app_token: str | None = None) -> dict | None:
|
||||
"""校验 IAM userToken,返回用户信息 dict 或 None。
|
||||
|
||||
调用 POST {IAM_BASE_URL}/api/iam/v2/identity/token/analyze,
|
||||
请求头携带 digi-middleware-auth-app 与 digi-middleware-auth-user。
|
||||
成功时返回包含 id/name/tenantId/tenantName 等字段的 dict。
|
||||
"""
|
||||
# 1. 查缓存
|
||||
now = time.time()
|
||||
cached = _cache.get(user_token)
|
||||
if cached is not None and (now - cached[1]) < settings.IAM_CACHE_TTL:
|
||||
return cached[0]
|
||||
|
||||
# 2. 调用 IAM analyze
|
||||
headers = {
|
||||
"digi-middleware-auth-user": user_token,
|
||||
"digi-middleware-auth-app": app_token or settings.IAM_APP_TOKEN,
|
||||
}
|
||||
try:
|
||||
client = _get_http_client()
|
||||
resp = await client.post(
|
||||
f"{settings.IAM_BASE_URL}/api/iam/v2/identity/token/analyze",
|
||||
headers=headers,
|
||||
)
|
||||
except Exception as ex:
|
||||
# IAM 不可达,缓存短时间避免雪崩
|
||||
_cache[user_token] = (None, now)
|
||||
print(f"[IAM] analyze 请求异常: {ex}")
|
||||
return None
|
||||
|
||||
if resp.status_code == 200:
|
||||
data = resp.json()
|
||||
# 兼容字段:id(用户标识)/ name(姓名)
|
||||
if data.get("id") or data.get("name"):
|
||||
_cache[user_token] = (data, now)
|
||||
return data
|
||||
# 返回体无用户标识,视为无效
|
||||
_cache[user_token] = (None, now)
|
||||
return None
|
||||
|
||||
# 非 200(token 无效/过期),缓存避免雪崩
|
||||
_cache[user_token] = (None, now)
|
||||
return None
|
||||
Reference in New Issue
Block a user