如何将Google Play内购与特定用户ID绑定以防止权限滥用
解决方案与变通方法
1. 用Google Play Billing的账户标识绑定应用用户ID
在发起订阅购买时,通过BillingFlowParams.Builder传入应用内唯一的用户ID(建议做哈希混淆处理,避免明文泄露)作为obfuscatedAccountId。该参数会与购买记录绑定,后续恢复购买时可精准筛选对应应用用户的订阅:
// 购买流程中设置混淆后的应用用户ID val billingFlowParams = BillingFlowParams.newBuilder() .setSkuDetails(skuDetails) .setObfuscatedAccountId(yourHashedAppUserId) // 替换为你的应用用户ID哈希值 .build() billingClient.launchBillingFlow(activity, billingFlowParams)
执行“恢复购买”时,调用queryPurchasesAsync后,仅保留purchase.accountIdentifiers.obfuscatedAccountId与当前登录应用用户ID匹配的记录,以此加载对应权限。
2. 结合Google Sign-In的稳定用户标识
如果应用支持Google登录,直接使用Google Sign-In返回的sub字段(用户唯一且稳定的标识,不受邮箱变更影响)作为绑定依据:
- 用户登录时解析
GoogleSignInAccount.getIdToken(),提取sub字段 - 购买时将
sub作为obfuscatedAccountId传入Billing参数 - 恢复购买时,校验购买记录中的标识与当前登录用户的
sub是否一致,仅匹配的订阅生效
3. 服务器端强制校验与订阅状态同步
客户端本地校验易被篡改,核心逻辑必须放在服务器端:
- 购买成功后,客户端将
purchase.token、应用用户ID、Google计费标识上传至服务器 - 服务器调用Google Play Developer API的
purchases.subscriptions:get接口,验证凭证有效性,将订阅状态与应用用户ID绑定存储 - 用户触发“恢复购买”时,客户端向服务器请求当前账号的订阅记录,服务器返回仅属于该用户的有效订阅(实时校验状态,解决应用外取消无法及时获知的问题)
- 启用Google Play的Real-Time Developer Notifications,订阅状态变更(取消、过期等)时,服务器会收到实时通知,及时更新用户权限
4. 跨账号登录的本地缓存清理
当用户切换应用账号时,立即清除本地存储的所有购买记录缓存,强制从服务器拉取新账号的订阅信息,避免同一设备上的旧账号购买记录被新账号错误加载。
内容的提问来源于stack exchange,提问作者Pythogen
相关产品推荐
相关产品推荐

