feat(auth): 小程序扫码登录其它端口 —— 生成小程序码(微信扫一扫自动拉起)
- wechat.get_wxacode(access_token缓存+getwxacodeunlimit),scene短token<=32 - /auth/mp-qr/start 返回 qr_image(小程序码,扫码自动打开小程序pages/scan-login) ,无凭据回退 qr_url - mp-qr gate 改 AUTH_WECHAT_QR(默认开)
This commit is contained in:
+22
-8
@@ -7,6 +7,7 @@
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import json
|
||||
import re
|
||||
import secrets
|
||||
@@ -670,17 +671,30 @@ async def wx_qr_poll(scene: str):
|
||||
|
||||
@router.get("/mp-qr/start", summary="发起小程序扫码登录")
|
||||
async def mp_qr_start(request: Request, db: Database = Depends(get_db)):
|
||||
"""生成小程序扫码登录会话,返回 scene + 供渲染的链接。"""
|
||||
if not config.AUTH_WECHAT_LOGIN:
|
||||
raise HTTPException(status_code=503, detail="小程序登录未开启")
|
||||
"""生成小程序扫码登录会话,返回 scene + 小程序码图片。
|
||||
|
||||
用于「小程序扫码登录其它端口」:桌面/admin/网页登录页展示该码,
|
||||
用户用 **微信扫一扫** → 自动打开小程序「扫码登录」页(复用其登录身份)确认,
|
||||
目标端口轮询取得登录令牌。scene 用短 token(wxacode 限 32 字符)。
|
||||
|
||||
未配置 WECHAT_APPID/SECRET 时退化为普通二维码(qr_url),仅支持「小程序内
|
||||
scanCode 路径」,无法被微信自动拉起小程序。
|
||||
"""
|
||||
if not config.AUTH_WECHAT_QR:
|
||||
raise HTTPException(status_code=503, detail="小程序扫码登录未开启")
|
||||
if not config.AUTH_ENABLED:
|
||||
raise HTTPException(status_code=403, detail="认证未开启")
|
||||
scene = wechat.new_scene()
|
||||
scene = f"mp_{secrets.token_hex(10)}" # 3+20 = 23 字符
|
||||
wx_qr_store.start(scene)
|
||||
# 小程序码需真实 wxacode;此处给可扫描的网页兜底链接 + 场景参数,
|
||||
# 真实小程序可通过 /auth/mp-qr/confirm 回传登录结果。前端据 qr_url 渲染二维码。
|
||||
qr_url = f"https://opc.pinesound.cn/mp/login?scene={scene}"
|
||||
return {"scene": scene, "qr_url": qr_url, "mp_enabled": True}
|
||||
# 生成小程序码(微信扫码自动打开小程序 pages/scan-login 并携带 scene)
|
||||
try:
|
||||
png = await wechat.get_wxacode(scene, page="pages/scan-login/index")
|
||||
b64 = base64.b64encode(png).decode("ascii")
|
||||
return {"scene": scene, "qr_image": f"data:image/png;base64,{b64}", "mp_enabled": True}
|
||||
except wechat.WechatError:
|
||||
# 无凭据/失败兜底:返回可扫描的 URL,前端按 qr_url 渲染普通二维码
|
||||
qr_url = f"https://opc.pinesound.cn/mp/login?scene={scene}"
|
||||
return {"scene": scene, "qr_url": qr_url, "mp_enabled": False}
|
||||
|
||||
|
||||
@router.get("/mp-qr/poll", summary="轮询小程序扫码登录状态")
|
||||
|
||||
Reference in New Issue
Block a user