ZHIWEI666 commited on
Commit
613a50c
·
verified ·
1 Parent(s): 1212fe9

Upload router_users.py

Browse files
Files changed (1) hide show
  1. router_users.py +41 -15
router_users.py CHANGED
@@ -1,5 +1,5 @@
1
  # router_users.py
2
- from fastapi import APIRouter, HTTPException, BackgroundTasks
3
  import time
4
  import re
5
  import random
@@ -261,38 +261,64 @@ async def update_user_profile(account: str, update_data: UserUpdate):
261
  db.save_data("users.json", users_db)
262
  return {"status": "success", "data": {k: v for k, v in user.items() if k != "password"}}
263
 
 
 
 
 
264
  @router.post("/api/users/reset_password")
265
- async def reset_password(pwd_data: PasswordReset):
266
- # 1. 直接从请求体中提取账号,不需要通过 URL 传参
267
- account = pwd_data.account
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
 
 
 
 
 
269
  users_db = db.load_data("users.json", default_data={})
270
- if account not in users_db: raise HTTPException(status_code=404, detail="用户不存在")
271
  user = users_db[account]
272
 
273
- # 🚀 核心排雷:严格匹配 models.py 中的驼峰命名 verifyType verifyContact
274
- if pwd_data.verifyType == "email" and user.get("email") != pwd_data.verifyContact:
275
  raise HTTPException(status_code=400, detail="填写的邮箱与该账号绑定的邮箱不匹配")
276
- if pwd_data.verifyType == "phone" and user.get("phone") != pwd_data.verifyContact:
277
  raise HTTPException(status_code=400, detail="填写的手机号与该账号绑定的手机号不匹配")
278
 
279
- cache_key = f"{pwd_data.verifyContact}_reset"
280
  cached = VERIFY_CODES.get(cache_key)
281
-
282
- # 安全获取过期时间防崩
283
  expire_time = cached.get("expires_at", cached.get("expires", 0)) if cached else 0
284
- if not cached or cached["code"] != pwd_data.code or time.time() > expire_time:
 
285
  raise HTTPException(status_code=400, detail="验证码不正确或已过期")
286
 
287
- if len(pwd_data.new_password) < 6: raise HTTPException(status_code=400, detail="新密码必须大于等于6个字符")
288
- if not re.match(r'^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};\':"\\|,.<>\/?]{6,}$', pwd_data.new_password): raise HTTPException(status_code=400, detail="新密码包含不支持的特殊字符")
289
 
290
  VERIFY_CODES.pop(cache_key, None)
291
- user["password"] = pwd_data.new_password
292
  db.save_data("users.json", users_db)
293
 
294
  return {"status": "success", "message": "密码修改成功"}
295
 
 
296
  @router.post("/api/users/follow")
297
  async def toggle_follow(follow: FollowToggle):
298
  users_db = db.load_data("users.json", default_data={})
 
1
  # router_users.py
2
+ from fastapi import APIRouter, HTTPException, BackgroundTasks, Request
3
  import time
4
  import re
5
  import random
 
261
  db.save_data("users.json", users_db)
262
  return {"status": "success", "data": {k: v for k, v in user.items() if k != "password"}}
263
 
264
+
265
+ # ==========================================
266
+ # 🚀 万能重置密码接口:杜绝所有前端数据格式 422 报错
267
+ # ==========================================
268
  @router.post("/api/users/reset_password")
269
+ async def reset_password(request: Request):
270
+ # 1. 万能解析器:兼容 JSON、双重字符串化、以及 FormData
271
+ try:
272
+ data = await request.json()
273
+ if isinstance(data, str): # 核心:拦截前端可能造成的"双重字符串化"
274
+ data = json.loads(data)
275
+ except:
276
+ try:
277
+ form = await request.form()
278
+ data = dict(form)
279
+ except:
280
+ raise HTTPException(status_code=400, detail="请求数据解析失败,请检查网络")
281
+
282
+ if not isinstance(data, dict):
283
+ raise HTTPException(status_code=400, detail=f"前端数据格式异常,收到的是: {type(data).__name__}")
284
+
285
+ # 2. 万能提取器:同时兼容前端的命名习惯误差
286
+ account = data.get("account")
287
+ new_password = data.get("new_password") or data.get("password")
288
+ verify_contact = data.get("verifyContact") or data.get("verify_contact") or data.get("email") or data.get("phone")
289
+ verify_type = data.get("verifyType") or data.get("verify_type") or data.get("contact_type")
290
+ code = data.get("code")
291
 
292
+ if not all([account, new_password, verify_contact, verify_type, code]):
293
+ raise HTTPException(status_code=400, detail="缺失必要参数 (账号/密码/验证码/联系方式),请检查表单")
294
+
295
+ # 3. 核心业务逻辑
296
  users_db = db.load_data("users.json", default_data={})
297
+ if account not in users_db: raise HTTPException(status_code=404, detail="用户不存在")
298
  user = users_db[account]
299
 
300
+ if verify_type == "email" and user.get("email") != verify_contact:
 
301
  raise HTTPException(status_code=400, detail="填写的邮箱与该账号绑定的邮箱不匹配")
302
+ if verify_type == "phone" and user.get("phone") != verify_contact:
303
  raise HTTPException(status_code=400, detail="填写的手机号与该账号绑定的手机号不匹配")
304
 
305
+ cache_key = f"{verify_contact}_reset"
306
  cached = VERIFY_CODES.get(cache_key)
 
 
307
  expire_time = cached.get("expires_at", cached.get("expires", 0)) if cached else 0
308
+
309
+ if not cached or cached["code"] != code or time.time() > expire_time:
310
  raise HTTPException(status_code=400, detail="验证码不正确或已过期")
311
 
312
+ if len(new_password) < 6: raise HTTPException(status_code=400, detail="新密码必须大于等于6个字符")
313
+ if not re.match(r'^[a-zA-Z0-9!@#$%^&*()_+\-=\[\]{};\':"\\|,.<>\/?]{6,}$', new_password): raise HTTPException(status_code=400, detail="新密码包含不支持的特殊字符")
314
 
315
  VERIFY_CODES.pop(cache_key, None)
316
+ user["password"] = new_password
317
  db.save_data("users.json", users_db)
318
 
319
  return {"status": "success", "message": "密码修改成功"}
320
 
321
+
322
  @router.post("/api/users/follow")
323
  async def toggle_follow(follow: FollowToggle):
324
  users_db = db.load_data("users.json", default_data={})