From 6ed6d382733d4682e5da2c99704d9a1de25fab16 Mon Sep 17 00:00:00 2001 From: Zayden Jung Date: Mon, 18 May 2026 23:39:56 +0800 Subject: [PATCH] secure avatar to s3 by exception control --- app/auth.py | 62 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/app/auth.py b/app/auth.py index c9dc294..2027559 100644 --- a/app/auth.py +++ b/app/auth.py @@ -72,31 +72,45 @@ async def auth_callback(request: Request, code: str, state: str): user_info = user_res.json() db = SessionLocal() + + try: + user = db.query(User).filter(User.email == user_info["email"]).first() - user = db.query(User).filter(User.email == user_info["email"]).first() - - if not user: - user = User( - google_id=user_info["id"], - email=user_info["email"], - name=user_info["name"], - avatar=user_info["picture"], - ) - db.add(user) - db.commit() - db.refresh(user) - - # 异步/同步将头像转存到 S3 - from app.utils.s3 import upload_google_avatar_to_s3 - s3_avatar_url = await upload_google_avatar_to_s3(user_info["picture"], str(user.id)) - - # 将更新后的 S3 URL 写回数据库 - user.avatar = s3_avatar_url - db.commit() - # 这里不需要再次 refresh,除非后面还要用到更新后的 user 对象 - # db.refresh(user) - - db.close() + if not user: + # 提取邮箱前缀作为 handle 基础 + # 比如 "john.doe@gmail.com" -> "john_doe" + base_handle = user_info["email"].split("@")[0].replace(".", "_").lower() + + # 拼接一个随机短字符串,确保 handle 的唯一性 + import secrets + random_suffix = secrets.token_hex(3) # 生成 6 位随机字符 + suggested_handle = f"{base_handle}_{random_suffix}" + + user = User( + google_id=user_info["id"], + email=user_info["email"], + name=user_info["name"], + avatar=user_info["picture"], + handle=suggested_handle, + ) + db.add(user) + db.commit() + db.refresh(user) + + # 异步/同步将头像转存到 S3 + from app.utils.s3 import upload_google_avatar_to_s3 + try: + s3_avatar_url = await upload_google_avatar_to_s3(user_info["picture"], str(user.id)) + # 将更新后的 S3 URL 写回数据库 + user.avatar = s3_avatar_url + db.commit() + except Exception as s3_err: + print(f"S3 Upload failed: {s3_err}") + + # 这里不需要再次 refresh,除非后面还要用到更新后的 user 对象 + # db.refresh(user) + finally: + db.close() jwt_token = create_jwt_token({ "sub": user.id,