From 2fd2e7df02bef8dc8cfdef47089fb18c0ac8fa36 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 8 Aug 2026 22:48:01 +0800 Subject: [PATCH] =?UTF-8?q?feat(backend/h5):=20=E5=9B=9E=E6=B5=81=20qrConn?= =?UTF-8?q?ect=20=E6=89=AB=E7=A0=81=E7=99=BB=E5=BD=95=E5=88=86=E6=94=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将生产服务器 api/h5.py 的 OAuth2 authorize 端点逻辑合回本地 src/backend: - 移除对非企微 UA 的硬拒(_require_wework_ua),改为 UA 检测分流 - 生产环境 + 外部浏览器返回 wwopen/sso/qrConnect 扫码登录 URL - 企微内 / 非生产环境仍走静默授权(snsapi_base) - 闭环「生产代码未入版本库」治理缺口(选项B部署时为保全扫码登录能力保留) Co-Authored-By: SeniorDeveloper --- src/backend/app/api/h5.py | 40 ++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/backend/app/api/h5.py b/src/backend/app/api/h5.py index e8a9b91..b191dc7 100644 --- a/src/backend/app/api/h5.py +++ b/src/backend/app/api/h5.py @@ -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] 外部浏览器访问 authorize,UA={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静默授权URL(snsapi_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})