fix: 扫码注册按俱乐部微信配置换openid,Referer识别小程序
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
"""俱乐部微信配置与 openid 解析。"""
|
"""俱乐部微信配置与 openid 解析。"""
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
@@ -8,6 +10,8 @@ from jituan.models import Club
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
_REFERER_APPID_RE = re.compile(r'servicewechat\.com/(wx[0-9a-fA-F]+)/', re.I)
|
||||||
|
|
||||||
|
|
||||||
def resolve_club_by_appid(app_id):
|
def resolve_club_by_appid(app_id):
|
||||||
if not app_id:
|
if not app_id:
|
||||||
@@ -38,6 +42,45 @@ def get_club_wx_credentials(club_id):
|
|||||||
return '', '', club
|
return '', '', club
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_club_id_for_wechat_request(request):
|
||||||
|
"""
|
||||||
|
小程序请求解析 club_id(登录/扫码注册)。
|
||||||
|
优先级:X-Club-Id > body.appId > Referer 内 wx appid > 默认 xq。
|
||||||
|
老端 fighter.js 的 wdlyhdl 未带头时,靠 Referer 识别星之界等俱乐部。
|
||||||
|
"""
|
||||||
|
from jituan.services.club_context import resolve_club_id_from_request
|
||||||
|
|
||||||
|
header = (request.META.get('HTTP_X_CLUB_ID') or '').strip()
|
||||||
|
if not header and hasattr(request, 'headers'):
|
||||||
|
header = (request.headers.get('X-Club-Id') or '').strip()
|
||||||
|
if header:
|
||||||
|
return header
|
||||||
|
|
||||||
|
app_id = ''
|
||||||
|
data = getattr(request, 'data', None) or {}
|
||||||
|
if isinstance(data, dict):
|
||||||
|
app_id = (data.get('appId') or data.get('app_id') or '').strip()
|
||||||
|
|
||||||
|
if not app_id:
|
||||||
|
referer = request.META.get('HTTP_REFERER', '') or ''
|
||||||
|
matched = _REFERER_APPID_RE.search(referer)
|
||||||
|
if matched:
|
||||||
|
app_id = matched.group(1)
|
||||||
|
|
||||||
|
if app_id:
|
||||||
|
club = resolve_club_by_appid(app_id)
|
||||||
|
if club:
|
||||||
|
return club.club_id
|
||||||
|
|
||||||
|
return resolve_club_id_from_request(request)
|
||||||
|
|
||||||
|
|
||||||
|
def wechat_jscode2session_for_request(request, code):
|
||||||
|
"""按请求上下文换取 openid(多俱乐部小程序)。"""
|
||||||
|
club_id = resolve_club_id_for_wechat_request(request)
|
||||||
|
return jscode2session(code, club_id=club_id)
|
||||||
|
|
||||||
|
|
||||||
def jscode2session(code, club_id=None, app_id=None):
|
def jscode2session(code, club_id=None, app_id=None):
|
||||||
"""
|
"""
|
||||||
按俱乐部微信配置换取 openid。
|
按俱乐部微信配置换取 openid。
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""邀请码 / 邀请链俱乐部隔离。"""
|
"""邀请码 / 邀请链俱乐部隔离。"""
|
||||||
from jituan.services.club_context import resolve_club_id_from_request
|
from jituan.services.club_resolver import resolve_club_id_for_wechat_request
|
||||||
from jituan.services.club_user import get_user_club_id
|
from jituan.services.club_user import get_user_club_id
|
||||||
|
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ def assert_invite_same_club(request, inviter_user, invitee_user=None):
|
|||||||
现网全部 xq 时行为与改造前一致。
|
现网全部 xq 时行为与改造前一致。
|
||||||
返回 (ok, message)
|
返回 (ok, message)
|
||||||
"""
|
"""
|
||||||
club_id = resolve_club_id_from_request(request)
|
club_id = resolve_club_id_for_wechat_request(request)
|
||||||
inviter_club = get_user_club_id(inviter_user)
|
inviter_club = get_user_club_id(inviter_user)
|
||||||
if inviter_club != club_id:
|
if inviter_club != club_id:
|
||||||
return False, '邀请码不属于当前小程序俱乐部'
|
return False, '邀请码不属于当前小程序俱乐部'
|
||||||
|
|||||||
@@ -113,8 +113,9 @@ class WechatMiniProgramLoginView(APIView):
|
|||||||
return Response({'code': 1, 'msg': '微信授权码不能为空', 'data': None},
|
return Response({'code': 1, 'msg': '微信授权码不能为空', 'data': None},
|
||||||
status=status.HTTP_400_BAD_REQUEST)
|
status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# 获取微信openid和unionid
|
# 获取微信openid和unionid(按俱乐部小程序配置)
|
||||||
wechat_data = self.get_wechat_openid(code)
|
from jituan.services.club_resolver import wechat_jscode2session_for_request
|
||||||
|
wechat_data = wechat_jscode2session_for_request(request, code)
|
||||||
if not wechat_data or 'openid' not in wechat_data:
|
if not wechat_data or 'openid' not in wechat_data:
|
||||||
error_msg = wechat_data.get('errmsg', '微信授权失败')
|
error_msg = wechat_data.get('errmsg', '微信授权失败')
|
||||||
return Response({'code': 2, 'msg': f'微信登录失败: {error_msg}', 'data': None},
|
return Response({'code': 2, 'msg': f'微信登录失败: {error_msg}', 'data': None},
|
||||||
@@ -833,10 +834,16 @@ class WechatLoginAndDashouRegisterView(APIView):
|
|||||||
'data': None
|
'data': None
|
||||||
}, status=status.HTTP_400_BAD_REQUEST)
|
}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
# 2. 获取微信openid
|
# 2. 获取微信openid(按俱乐部小程序 appid,勿用全局星阙配置)
|
||||||
wechat_data = self.get_wechat_openid(code)
|
from jituan.services.club_resolver import (
|
||||||
|
resolve_club_id_for_wechat_request,
|
||||||
|
wechat_jscode2session_for_request,
|
||||||
|
)
|
||||||
|
club_id = resolve_club_id_for_wechat_request(request)
|
||||||
|
wechat_data = wechat_jscode2session_for_request(request, code)
|
||||||
if not wechat_data or 'openid' not in wechat_data:
|
if not wechat_data or 'openid' not in wechat_data:
|
||||||
error_msg = wechat_data.get('errmsg', '微信授权失败')
|
error_msg = wechat_data.get('errmsg', '微信授权失败')
|
||||||
|
logger.warning('wdlyhdl 微信登录失败 club=%s err=%s', club_id, error_msg)
|
||||||
return Response({
|
return Response({
|
||||||
'code': 4,
|
'code': 4,
|
||||||
'msg': f'微信登录失败: {error_msg}',
|
'msg': f'微信登录失败: {error_msg}',
|
||||||
@@ -880,7 +887,7 @@ class WechatLoginAndDashouRegisterView(APIView):
|
|||||||
|
|
||||||
from jituan.services.invite_guard import assert_invite_same_club
|
from jituan.services.invite_guard import assert_invite_same_club
|
||||||
from jituan.services.club_user import ensure_user_club_id
|
from jituan.services.club_user import ensure_user_club_id
|
||||||
from jituan.services.club_context import resolve_club_id_from_request
|
from jituan.services.club_resolver import resolve_club_id_for_wechat_request
|
||||||
|
|
||||||
ok, invite_msg = assert_invite_same_club(
|
ok, invite_msg = assert_invite_same_club(
|
||||||
request, guanshi_profile.user, user_main,
|
request, guanshi_profile.user, user_main,
|
||||||
@@ -892,7 +899,7 @@ class WechatLoginAndDashouRegisterView(APIView):
|
|||||||
'data': None
|
'data': None
|
||||||
}, status=status.HTTP_403_FORBIDDEN)
|
}, status=status.HTTP_403_FORBIDDEN)
|
||||||
|
|
||||||
ensure_user_club_id(user_main, resolve_club_id_from_request(request))
|
ensure_user_club_id(user_main, resolve_club_id_for_wechat_request(request))
|
||||||
|
|
||||||
# 验证管事状态
|
# 验证管事状态
|
||||||
|
|
||||||
@@ -1261,7 +1268,8 @@ class WechatLoginAndGuanshiRegisterView(APIView):
|
|||||||
return Response({'code': 400, 'msg': '邀请码长度超过限制', 'data': None},
|
return Response({'code': 400, 'msg': '邀请码长度超过限制', 'data': None},
|
||||||
status=status.HTTP_400_BAD_REQUEST)
|
status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
wechat_data = self._get_wechat_openid(code)
|
from jituan.services.club_resolver import wechat_jscode2session_for_request
|
||||||
|
wechat_data = wechat_jscode2session_for_request(request, code)
|
||||||
if not wechat_data or 'openid' not in wechat_data:
|
if not wechat_data or 'openid' not in wechat_data:
|
||||||
error_msg = wechat_data.get('errmsg', '微信授权失败')
|
error_msg = wechat_data.get('errmsg', '微信授权失败')
|
||||||
return Response({'code': 400, 'msg': f'微信登录失败: {error_msg}', 'data': None},
|
return Response({'code': 400, 'msg': f'微信登录失败: {error_msg}', 'data': None},
|
||||||
|
|||||||
Reference in New Issue
Block a user