借助Firebase Function校验Google Play订阅:跨谷歌服务认证咨询
我来帮你梳理下在Firebase Functions里对接谷歌服务(这里默认是指Google Play订阅验证相关服务)做用户订阅状态判断的认证流程,都是实际项目里验证过的实用步骤:
核心认证思路:服务账号实现服务器到服务器的无交互认证
因为Firebase Functions是后端环境,没法走用户端OAuth授权那一套,最安全可靠的方式是用谷歌服务账号完成两个服务间的身份校验。
1. 创建并配置谷歌服务账号
- 打开谷歌云控制台,找到你绑定Firebase的项目,进入「IAM与管理员」→「服务账号」页面
- 新建一个服务账号,给它分配精准的权限:如果是验证Google Play订阅,就给它添加「Google Play Developer API Client」权限,或者更细粒度的「查看应用订阅数据」权限,遵循权限最小化原则
- 下载该服务账号的JSON密钥文件,记住:这个文件绝对不能上传到代码仓库、公开存储或者客户端代码里,属于敏感信息
2. 在Firebase Functions中配置密钥
有两种安全的配置方式,推荐第二种:
- 方式一:用Firebase环境变量存储
在本地终端运行命令:
部署后,函数里可以通过firebase functions:config:set google.service_account="$(cat path/to/your/service-account-key.json)"functions.config().google.service_account获取密钥内容 - 方式二:关联GCP服务账号(更安全)
如果你的Firebase Functions部署在GCP上,直接在GCP控制台给目标函数关联刚才创建的服务账号,不用手动管理密钥文件,GCP会自动处理认证
3. 在Functions代码中实现认证+订阅验证逻辑
以验证Google Play订阅为例,先安装依赖:
npm install googleapis
然后写云函数代码:
const functions = require("firebase-functions"); const { google } = require("googleapis"); // 初始化谷歌认证客户端 async function getAuthClient() { const serviceAccount = JSON.parse(functions.config().google.service_account); // 订阅验证需要的权限 scope return google.auth.fromJSON(serviceAccount).createScoped([ "https://www.googleapis.com/auth/androidpublisher" ]); } // 供客户端调用的订阅验证函数 exports.checkUserSubscription = functions.https.onCall(async (data, context) => { // 第一步:先验证请求来自已登录的Firebase用户 if (!context.auth) { throw new functions.https.HttpsError("unauthenticated", "请先登录账号"); } const { packageName, subscriptionId, purchaseToken } = data; if (!packageName || !subscriptionId || !purchaseToken) { throw new functions.https.HttpsError("invalid-argument", "缺少必要参数"); } try { const authClient = await getAuthClient(); const androidPublisher = google.androidpublisher({ version: "v3", auth: authClient }); // 调用Google Play API查询订阅状态 const response = await androidPublisher.purchases.subscriptions.get({ packageName, subscriptionId, token: purchaseToken }); // 判断订阅是否有效:过期时间晚于当前时间即为活跃状态 const isActive = response.data.expiryTimeMillis > Date.now(); return { isActive, subscriptionDetails: response.data }; } catch (error) { functions.logger.error("订阅验证失败", error); throw new functions.https.HttpsError("internal", "订阅验证出错,请稍后重试"); } });
4. 几个关键注意事项
- 用户身份绑定:一定要验证客户端传入的
purchaseToken属于当前context.auth.uid对应的用户,防止恶意用户用他人的token查询订阅状态 - 配额优化:Google Play API有调用配额限制,对于频繁查询的订阅,可以缓存验证结果(比如存到Firebase Firestore),减少API调用次数
- 错误处理:要捕获API返回的各种错误(比如token无效、权限不足、API配额耗尽等),给客户端返回清晰的错误提示
内容的提问来源于stack exchange,提问作者Alguru
相关产品推荐
相关产品推荐

