如何通过Node.js后端完成Google Play应用内购的鉴权与验证?
Google Play内购Node.js服务器端鉴权验证补全与详解
嘿,你已经搞定了Android端内购集成和Firebase的数据上传,接下来就差把Node.js这边的签名验证逻辑补全啦!我帮你把你写的那段代码完善起来,再给你拆解每个关键步骤,确保验证万无一失:
完整的签名验证代码
var crypto = require('crypto'); // 替换成你在Google Play控制台获取的公钥(注意不要泄露!) var publicKey = "你的Google Play公钥"; // 从Firebase读取的购买详情(前端要原封不动上传Google Play返回的purchaseData) var signedData = { "orderId":"ORDER_ID", "packageName":"com.example.app", "productId":"你的商品ID", "purchaseTime":1620000000000, "purchaseState":0, "purchaseToken":"购买凭证Token" }; // 同样从Firebase读取的签名字符串(前端上传的signature) var signature = "从前端获取的签名值"; function verifyGooglePlayPurchase(signedData, signature, publicKey) { try { // 把Google Play的原始公钥转换成crypto模块需要的PEM格式 const formattedPublicKey = `-----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`; // 创建RSA-SHA1验证器(Google Play内购签名用的是这个算法) const verifier = crypto.createVerify('RSA-SHA1'); // 传入要验证的原始数据:必须是和Google Play返回的完全一致的JSON字符串 verifier.update(JSON.stringify(signedData)); // 验证签名:signature是base64编码的,所以指定编码为base64 return verifier.verify(formattedPublicKey, signature, 'base64'); } catch (err) { console.error("验证过程出错:", err); return false; } } // 执行验证 const isPurchaseLegitimate = verifyGooglePlayPurchase(signedData, signature, publicKey); if (isPurchaseLegitimate) { console.log("✅ 购买验证通过!可以给用户解锁功能啦"); // 这里可以添加业务逻辑:比如更新用户权限、记录有效订单到数据库等 } else { console.log("❌ 购买验证失败!可能是数据被篡改或者签名无效"); }
必须踩准的几个关键点
- 公钥格式不能错:Google Play给的公钥是没有头部尾部和换行的,必须手动加上
-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----,不然crypto模块会直接报错。 - 数据要原封不动:前端上传的
signedData必须和Google Play返回的JSON完全一致,不能改字段顺序、加空格或者删字段——验签是对原始数据的哈希值做的,一点点改动都会导致验证失败。 - 购买状态要检查:除了验签,一定要看
signedData里的purchaseState字段,只有0代表购买成功,1是取消购买,2是退款,这些情况都不能算有效购买。 - 异常不能忽略:加try-catch是必须的,比如公钥写错、签名格式不对这些情况都会抛出异常,别让验证逻辑搞崩你的服务器。
额外的安全小建议
- 别把公钥硬写在代码里!存到环境变量或者配置中心,防止代码泄露导致公钥外流。
- 验证通过后,把
purchaseToken和用户ID绑定存起来,防止同一个凭证被重复用来解锁功能。 - Firebase的安全规则要配置好,只有你的Node.js服务器能读写购买记录,别让前端随便改数据。
内容的提问来源于stack exchange,提问作者Bucky
相关产品推荐
相关产品推荐

