fix: 微信登录统一使用 unionid 匹配,增加调试信息

- 统一 H5 和 PC 模式都只用 unionid 匹配用户
- 没有 unionid 时返回错误,不再用 openid 兜底创建新用户
- 增加调试参数:debug_openid、debug_unionid、debug_keys_in_userinfo 等
- 修复重定向路径:/auth/signin → /home(原路径不存在)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-12-11 14:14:25 +08:00
parent 35823fd61f
commit fa14346ca2

49
app.py
View File

@@ -3707,18 +3707,18 @@ def wechat_callback():
if state and wechat_session_exists(state):
update_wechat_session(state, {'status': 'auth_denied', 'error': '用户拒绝授权'})
print(f"❌ 用户拒绝授权: state={state}")
return redirect('/auth/signin?error=wechat_auth_denied')
return redirect('/home?error=wechat_auth_denied')
# 参数验证
if not code or not state:
if state and wechat_session_exists(state):
update_wechat_session(state, {'status': 'auth_failed', 'error': '授权参数缺失'})
return redirect('/auth/signin?error=wechat_auth_failed')
return redirect('/home?error=wechat_auth_failed')
# 从 Redis 获取 session自动处理过期
session_data = get_wechat_session(state)
if not session_data:
return redirect('/auth/signin?error=session_expired')
return redirect('/home?error=session_expired')
try:
# 步骤1: 用户已扫码并授权(微信回调过来说明用户已完成扫码+授权)
@@ -3741,7 +3741,7 @@ def wechat_callback():
if not token_data:
update_wechat_session(state, {'status': 'auth_failed', 'error': '获取访问令牌失败'})
print(f"❌ 获取微信access_token失败: state={state}")
return redirect('/auth/signin?error=token_failed')
return redirect('/home?error=token_failed')
# 步骤3: Token获取成功标记为已授权
update_wechat_session(state, {'status': 'authorized'})
@@ -3752,7 +3752,7 @@ def wechat_callback():
if not user_info:
update_wechat_session(state, {'status': 'auth_failed', 'error': '获取用户信息失败'})
print(f"❌ 获取微信用户信息失败: openid={token_data['openid']}")
return redirect('/auth/signin?error=userinfo_failed')
return redirect('/home?error=userinfo_failed')
# 查找或创建用户 / 或处理绑定
openid = token_data['openid']
@@ -3763,11 +3763,11 @@ def wechat_callback():
try:
target_user_id = session.get('user_id') or session_data.get('bind_user_id')
if not target_user_id:
return redirect('/auth/signin?error=bind_no_user')
return redirect('/home?error=bind_no_user')
target_user = User.query.get(target_user_id)
if not target_user:
return redirect('/auth/signin?error=bind_user_missing')
return redirect('/home?error=bind_user_missing')
# 检查该微信是否已被其他账户绑定
existing = None
@@ -3796,10 +3796,25 @@ def wechat_callback():
user = None
is_new_user = False
if unionid:
# 统一使用 unionid 匹配用户H5 和 PC 模式都一样)
if not unionid:
# 没有获取到 unionid无法关联账号
mode_name = 'H5' if session_data.get('mode') == 'h5' else 'PC'
update_wechat_session(state, {'status': 'auth_failed', 'error': f'{mode_name}授权未返回unionid'})
print(f"{mode_name} 授权未返回 unionid, openid={openid}, user_info={user_info}")
# 调试信息:将微信返回的数据通过 URL 传给前端
debug_params = urllib.parse.urlencode({
'error': 'no_unionid',
'debug_mode': mode_name,
'debug_openid': openid[:10] + '...' if openid else 'null',
'debug_has_unionid_in_token': '1' if token_data.get('unionid') else '0',
'debug_has_unionid_in_userinfo': '1' if user_info.get('unionid') else '0',
'debug_nickname': user_info.get('nickname', '')[:10],
'debug_keys_in_userinfo': ','.join(user_info.keys()) if user_info else 'null',
})
return redirect(f'/home?{debug_params}')
user = User.query.filter_by(wechat_union_id=unionid).first()
if not user:
user = User.query.filter_by(wechat_open_id=openid).first()
if not user:
# 创建新用户
@@ -3851,7 +3866,17 @@ def wechat_callback():
# 清理 session
delete_wechat_session(state)
print(f"✅ H5 微信登录成功,重定向到: {frontend_redirect}")
return redirect(f"{frontend_redirect}?wechat_login=success")
# 调试信息:携带微信返回的关键数据
debug_params = urllib.parse.urlencode({
'wechat_login': 'success',
'debug_is_new_user': '1' if is_new_user else '0',
'debug_has_unionid': '1' if unionid else '0',
'debug_unionid': (unionid[:10] + '...') if unionid else 'null',
'debug_openid': (openid[:10] + '...') if openid else 'null',
'debug_user_id': user.id,
'debug_nickname': user_info.get('nickname', '')[:10],
})
return redirect(f"{frontend_redirect}?{debug_params}")
# PC 扫码模式:更新状态供前端轮询
if not mode:
@@ -3872,7 +3897,7 @@ def wechat_callback():
if wechat_session_exists(state):
update_wechat_session(state, {'status': 'auth_failed', 'error': str(e)})
return redirect('/auth/signin?error=login_failed')
return redirect('/home?error=login_failed')
@app.route('/api/auth/login/wechat', methods=['POST'])