fix zgame laluparty launch params
This commit is contained in:
parent
e5654e9b7c
commit
68cabb493d
@ -301,6 +301,10 @@ func (s *Service) LaunchGame(ctx context.Context, command LaunchCommand) (Launch
|
||||
}
|
||||
token = "gt_" + randomHex(24)
|
||||
}
|
||||
if strings.EqualFold(game.AdapterType, gamedomain.AdapterZGameV1) {
|
||||
// ZGame 文档要求 js_code 是客户服务器派发的短期凭证;不能把 App access token 泄漏到三方 H5 URL。
|
||||
token = "gt_" + randomHex(24)
|
||||
}
|
||||
sessionTTL := s.config.LaunchSessionTTL
|
||||
// 三方游戏会在 H5 运行期间持续回调 token;厂商适配器可以把默认 15 分钟启动 TTL 拉长。
|
||||
if strings.EqualFold(game.AdapterType, gamedomain.AdapterYomiV4) {
|
||||
@ -995,24 +999,15 @@ func buildLaunchURL(game gamedomain.LaunchableGame, session gamedomain.LaunchSes
|
||||
return parsed.String(), nil
|
||||
}
|
||||
if strings.EqualFold(game.AdapterType, gamedomain.AdapterZGameV1) {
|
||||
// ZGame 默认 channelName=zgame_demo 会走 iframe parent postMessage;App WebView 必须切到 wh 模式,让 SDK 从 URL 读取 openId/js_code。
|
||||
// token/code/js_code/session 四个别名仍指向同一个短期启动令牌,兼容厂商不同入口读取字段。
|
||||
// laluparty 是厂商文档约定通道;H5 通过 App 注入的 ThirdPlatformBridge 取用户信息和 login js_code。
|
||||
// 启动 URL 仍带 open_id/js_code,供 App Bridge 复用同一份短期凭证,避免客户端再发起一次派码请求。
|
||||
config := zgameConfigFromPlatform(game)
|
||||
openID := externalUserID(session, config.UIDMode)
|
||||
query.Set("channelName", "wh")
|
||||
query.Set("channel_name", "wh")
|
||||
query.Set("cv", "Android")
|
||||
query.Set("openId", openID)
|
||||
query.Set("channelName", "laluparty")
|
||||
query.Set("open_id", openID)
|
||||
query.Set("userId", openID)
|
||||
query.Set("uid", openID)
|
||||
query.Set("userName", openID)
|
||||
query.Set("user_name", openID)
|
||||
query.Set("balance", "0")
|
||||
query.Set("token", token)
|
||||
query.Set("code", token)
|
||||
query.Set("openId", openID)
|
||||
query.Set("js_code", token)
|
||||
query.Set("session", token)
|
||||
query.Set("jscode", token)
|
||||
query.Set("gameId", strings.TrimSpace(session.ProviderGameID))
|
||||
query.Set("game_id", strings.TrimSpace(session.ProviderGameID))
|
||||
callbackBase := config.CallbackBaseValue()
|
||||
|
||||
@ -598,21 +598,19 @@ func TestLaunchGameBuildsZGameURL(t *testing.T) {
|
||||
if parsed.Scheme+"://"+parsed.Host+parsed.Path != "https://zgame.example/h5/1001" {
|
||||
t.Fatalf("zgame launch url must use per-game configured url: %s", result.LaunchURL)
|
||||
}
|
||||
jsCode := parsed.Query().Get("js_code")
|
||||
if jsCode == "" || !strings.HasPrefix(jsCode, "gt_") || jsCode == token {
|
||||
t.Fatalf("zgame launch must expose a scoped js_code instead of app token: %q", jsCode)
|
||||
}
|
||||
if repo.session.LaunchTokenHash != stableHash(jsCode) {
|
||||
t.Fatalf("zgame launch session must be bound to scoped js_code")
|
||||
}
|
||||
expected := map[string]string{
|
||||
"channelName": "wh",
|
||||
"channel_name": "wh",
|
||||
"cv": "Android",
|
||||
"channelName": "laluparty",
|
||||
"openId": "420001",
|
||||
"open_id": "420001",
|
||||
"userId": "420001",
|
||||
"uid": "420001",
|
||||
"userName": "420001",
|
||||
"user_name": "420001",
|
||||
"balance": "0",
|
||||
"token": token,
|
||||
"code": token,
|
||||
"js_code": token,
|
||||
"session": token,
|
||||
"js_code": jsCode,
|
||||
"jscode": jsCode,
|
||||
"gameId": "1001",
|
||||
"game_id": "1001",
|
||||
"callbackBase": "https://api.example.test/api/v1/zgame/callback",
|
||||
@ -632,6 +630,11 @@ func TestLaunchGameBuildsZGameURL(t *testing.T) {
|
||||
t.Fatalf("zgame launch query %s mismatch: got %q want %q url=%s", key, got, want, result.LaunchURL)
|
||||
}
|
||||
}
|
||||
for _, key := range []string{"token", "code", "session", "cv", "channel_name"} {
|
||||
if got := parsed.Query().Get(key); got != "" {
|
||||
t.Fatalf("zgame launch query must not expose %s=%q url=%s", key, got, result.LaunchURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLaunchGameRequiresBaishunLaunchURL(t *testing.T) {
|
||||
|
||||
@ -59,6 +59,10 @@ func zgameConfigFromPlatform(value any) zgameAdapterConfig {
|
||||
var config zgameAdapterConfig
|
||||
_ = json.Unmarshal([]byte(strings.TrimSpace(raw)), &config)
|
||||
config.UIDMode = strings.ToLower(strings.TrimSpace(config.UIDMode))
|
||||
if config.UIDMode == "" {
|
||||
// laluparty 游戏侧展示和签名都用短号作为 open_id;历史配置未写 uid_mode 时按文档默认走 display_user_id。
|
||||
config.UIDMode = "display_user_id"
|
||||
}
|
||||
config.DefaultLang = strings.TrimSpace(config.DefaultLang)
|
||||
config.LaunchURLTemplate = strings.TrimSpace(config.LaunchURLTemplate)
|
||||
config.CallbackBase = strings.TrimSpace(firstNonEmpty(config.CallbackBase, config.CallbackBaseAlias))
|
||||
@ -159,7 +163,7 @@ func (s *Service) handleZGameLogin(ctx context.Context, app string, config zgame
|
||||
if err != nil {
|
||||
return zgameAdapterError(zgameCodeFromError(err), zgameMessageFromError(err), true, "")
|
||||
}
|
||||
raw, contentType := zgameJSON(zgameCodeOK, "success", zgameLoginData(session, config, jsCode, snapshot, s.now()))
|
||||
raw, contentType := zgameJSON(zgameCodeOK, "success", zgameLoginData(session, config, openID, jsCode, snapshot, s.now()))
|
||||
return raw, contentType, strconv.Itoa(zgameCodeOK), true, "", nil
|
||||
}
|
||||
|
||||
@ -339,7 +343,7 @@ func (s *Service) validZGameSession(ctx context.Context, app string, platformCod
|
||||
if token == "" {
|
||||
return gamedomain.LaunchSession{}, xerr.New(xerr.Unauthorized, "session invalid")
|
||||
}
|
||||
// 当前 ZGame 不要求 App 原生生成一次性 jscode;优先消费 App access token,远程桥接脚本即可免发版接入。
|
||||
// 新版启动链路使用服务端短期 js_code;保留 JWT 兼容旧测试链接,避免已打开的 H5 立即失效。
|
||||
if strings.Count(token, ".") == 2 {
|
||||
if session, err := s.appSessionFromAccessToken(app, token); err == nil {
|
||||
return session, nil
|
||||
@ -377,8 +381,11 @@ func zgameSignatureValid(openID string, session string, signature string, secret
|
||||
return subtle.ConstantTimeCompare([]byte(strings.ToLower(signature)), []byte(expected)) == 1
|
||||
}
|
||||
|
||||
func zgameLoginData(session gamedomain.LaunchSession, config zgameAdapterConfig, token string, snapshot yomiUserSnapshot, now time.Time) map[string]any {
|
||||
openID := externalUserID(session, config.UIDMode)
|
||||
func zgameLoginData(session gamedomain.LaunchSession, config zgameAdapterConfig, requestedOpenID string, token string, snapshot yomiUserSnapshot, now time.Time) map[string]any {
|
||||
openID := strings.TrimSpace(requestedOpenID)
|
||||
if openID == "" {
|
||||
openID = externalUserID(session, config.UIDMode)
|
||||
}
|
||||
return map[string]any{
|
||||
"session": token,
|
||||
"session_expired": zgameSessionTTLMS(session, now),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user