mini_auth.py 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. """小程序鉴权:微信手机号快捷登录。"""
  2. from __future__ import annotations
  3. from datetime import datetime
  4. from fastapi import APIRouter, Depends
  5. from sqlalchemy.orm import Session
  6. from app.core.database import get_db
  7. from app.core.response import error_response, success_response
  8. from app.services.web_login_tokens import issue_web_login_tokens
  9. from app.services.wechat_login_service import resolve_wechat_login_user
  10. from app.services.wechat_mini_auth import (
  11. WechatMiniAuthError,
  12. code2session,
  13. get_phone_number,
  14. )
  15. router = APIRouter(prefix="/mini/auth", tags=["小程序鉴权"])
  16. @router.post("/wechat-login", response_model=dict)
  17. def wechat_login(body: dict, db: Session = Depends(get_db)):
  18. """手机号快捷登录:须 loginCode + phoneCode;匹配 phone_no 并绑定 wx_openid。"""
  19. login_code = (body.get("loginCode") or "").strip()
  20. phone_code = (body.get("phoneCode") or "").strip()
  21. if not phone_code:
  22. return error_response(400, "请授权手机号登录,或使用账号密码登录")
  23. try:
  24. sess = code2session(login_code)
  25. except WechatMiniAuthError as exc:
  26. return error_response(400, str(exc))
  27. try:
  28. phone = get_phone_number(phone_code)
  29. except WechatMiniAuthError as exc:
  30. return error_response(400, str(exc))
  31. user, err_msg, err_code = resolve_wechat_login_user(
  32. db, openid=sess["openid"], phone=phone
  33. )
  34. if err_msg:
  35. return error_response(err_code or 400, err_msg)
  36. unionid = (sess.get("unionid") or "").strip()
  37. if unionid and not (getattr(user, "wx_unionid", None) or "").strip():
  38. user.wx_unionid = unionid
  39. user.update_time = datetime.now()
  40. db.add(user)
  41. db.commit()
  42. db.refresh(user)
  43. try:
  44. data = issue_web_login_tokens(db, user)
  45. except ValueError as exc:
  46. return error_response(403, str(exc))
  47. return success_response(data)