fix: prioritize zeeone app access token session

This commit is contained in:
zhx 2026-05-25 16:33:18 +08:00
parent 2df7d8b59e
commit 597b1cf587
2 changed files with 52 additions and 0 deletions

View File

@ -816,6 +816,51 @@ func TestHandleZeeOneUserInfoChangeBalanceAndUpdateSession(t *testing.T) {
}
}
func TestHandleZeeOneAccessTokenIgnoresStaleLaunchSessionGameID(t *testing.T) {
secret := "zeeone-test-secret"
token := leaderccTestAccessToken(t, "lalu", 123456, "123456", 1700003600)
repo := &fakeRepository{
platform: gamedomain.Platform{
PlatformCode: "zeeone",
AdapterType: gamedomain.AdapterZeeOneV1,
CallbackSecretCiphertext: secret,
AdapterConfigJSON: `{"merchant_id":307715,"platform_id":2032,"uid_mode":"display_user_id"}`,
},
// 同一个 App access token 启动过其他 ZeeOne 游戏时,旧启动会话会留下同 hash 但不同 provider_game_id。
// 回调必须以 JWT 用户身份为准,不能被旧会话的 game_id 拦截成 sessionId invalid。
session: gamedomain.LaunchSession{
AppCode: "lalu",
SessionID: "old_launch_session",
UserID: 123456,
DisplayUserID: "123456",
ProviderGameID: "1021",
LaunchTokenHash: stableHash(token),
Status: gamedomain.SessionActive,
ExpiresAtMS: 1700003600000,
},
}
wallet := &fakeWallet{balanceAfter: 900}
svc := New(Config{}, repo, wallet, &fakeUser{})
svc.now = func() time.Time { return time.UnixMilli(1700000000000) }
changeBody := `{"appId":"M307715_P2032","userId":"123456","sessionId":"` + token + `","currency_diff":-100,"diff_msg":"bet","game_id":1032,"room_id":"6","change_time_at":1700000000,"order_id":"zee_order_stale_session"}`
raw, _, err := svc.HandleCallback(context.Background(), &gamev1.CallbackRequest{
Meta: &gamev1.RequestMeta{RequestId: "req-zeeone-stale-session", AppCode: "lalu"},
PlatformCode: "zeeone",
Operation: "change_balance",
RawBody: zeeoneTestEnvelope(t, secret, changeBody, 1700000000000),
})
if err != nil {
t.Fatalf("HandleCallback change failed: %v", err)
}
if !strings.Contains(string(raw), `"code":0`) || strings.Contains(string(raw), "sessionId invalid") {
t.Fatalf("zeeone access token should ignore stale launch session game id: %s", raw)
}
if wallet.lastApply.GetUserId() != 123456 || wallet.lastApply.GetGameId() != "1032" {
t.Fatalf("zeeone wallet command must use JWT user and callback game id, got %+v", wallet.lastApply)
}
}
func TestHandleBaishunSSTokenUserInfoUpdateAndChangeBalance(t *testing.T) {
secret := "baishun-test-app-key"
token := "app_access_token_baishun"

View File

@ -325,6 +325,13 @@ func (s *Service) validZeeOneSession(ctx context.Context, app string, sessionID
if sessionID == "" {
return gamedomain.LaunchSession{}, xerr.New(xerr.Unauthorized, "sessionId not found")
}
// ZeeOne 约定 sessionId 直接使用 App access token同一个登录 token 可能启动多款游戏。
// 因此 JWT 必须优先解析,否则会先命中 game_launch_sessions 里旧游戏的 hash导致 game_id 校验误判。
if strings.Count(sessionID, ".") == 2 {
if session, err := s.appSessionFromAccessToken(app, sessionID); err == nil {
return session, nil
}
}
if session, err := s.validYomiSession(ctx, app, sessionID); err == nil {
return session, nil
}