feat(backend/h5): 回流 qrConnect 扫码登录分支

将生产服务器 api/h5.py 的 OAuth2 authorize 端点逻辑合回本地 src/backend:
- 移除对非企微 UA 的硬拒(_require_wework_ua),改为 UA 检测分流
- 生产环境 + 外部浏览器返回 wwopen/sso/qrConnect 扫码登录 URL
- 企微内 / 非生产环境仍走静默授权(snsapi_base)
- 闭环「生产代码未入版本库」治理缺口(选项B部署时为保全扫码登录能力保留)

Co-Authored-By: SeniorDeveloper <expert>
This commit is contained in:
Simon
2026-08-08 22:48:01 +08:00
parent b80ebf1d7c
commit 2fd2e7df02
+27 -13
View File
@@ -260,8 +260,12 @@ async def get_oauth_authorize_url(
Returns:
Dict: 统一响应格式,包含 authorize_url 字段
"""
# 后端第二道防线:非企微环境拒绝授权
_require_wework_ua(request)
# UA 检测:企微 WebView vs 外部浏览器(不再硬拒,改为按来源分流)
ua = request.headers.get("user-agent", "")
is_wework = bool(_WEWORK_UA_RE.search(ua))
# 生产环境且非企微时仅记录日志,不拒绝(改为走扫码登录)
if is_production() and not is_wework:
logger.info(f"[OAuth] 外部浏览器访问 authorizeUA={ua[:80]},将返回扫码登录URL")
corp_id = settings.wecom_corp_id
@@ -277,17 +281,27 @@ async def get_oauth_authorize_url(
default_origin = settings.cors_origins_list[0] if settings.cors_origins_list else "https://localhost"
encoded_redirect = quote(f"{default_origin}/itdesk/", safe="")
# 构造企微OAuth2静默授权URLsnsapi_base:用户无感知)
# 企业微信 OAuth2 地址(注意是 open.work.weixin.qq.com
authorize_url = (
f"https://open.work.weixin.qq.com/connect/oauth2/authorize"
f"?appid={corp_id}"
f"&redirect_uri={encoded_redirect}"
f"&response_type=code"
f"&scope=snsapi_base"
f"&state=STATE"
f"#wechat_redirect"
)
if is_wework or not is_production():
# 企微内(或非生产环境):静默授权(snsapi_base,用户无感知
authorize_url = (
f"https://open.work.weixin.qq.com/connect/oauth2/authorize"
f"?appid={corp_id}"
f"&redirect_uri={encoded_redirect}"
f"&response_type=code"
f"&scope=snsapi_base"
f"&state=STATE"
f"#wechat_redirect"
)
else:
# 外部浏览器 + 生产环境:扫码登录(qrConnect)
agent_id = getattr(settings, "wecom_agent_id", "1000002")
authorize_url = (
f"https://open.work.weixin.qq.com/wwopen/sso/qrConnect"
f"?appid={corp_id}"
f"&agentid={agent_id}"
f"&redirect_uri={encoded_redirect}"
f"&state=STATE"
)
return success_response(data={"authorize_url": authorize_url})