node.js - 检索秘密 Firebase 服务帐户 json
问题描述
我在 nextjs 中有这段代码,它应该检查令牌是否有效,然后登录用户。
const firebaseAdmin = require("firebase-admin");
const serviceAccount = require ('../secret.json');
export const verifyIdToken = async (token) => {
if (!firebaseAdmin.apps.length) {
firebaseAdmin.initializeApp({
// credential: firebaseAdmin.credential.cert(serviceAccount),
credential: firebaseAdmin.credential.applicationDefault(),
databaseURL: "rtdb.firebaseio.com",
});
}
return await firebaseAdmin
.auth()
.verifyIdToken(token)
.catch((error) => {
throw error;
});
};
据我了解,我将 Windows 环境变量设置为 firebase 推荐并切换到使用applicationDefault()
since ,
ADC 可以自动找到您的凭据
问题是应用程序只能在本地工作。当我部署网站时,令牌未经过验证并产生错误。我通过云功能为 NextJs 应用程序提供服务。我该如何解决这个问题。错误是
auth/invalid-credential
Must initialize app with a cert credential or set your Firebase project
ID as the GOOGLE_CLOUD_PROJECT environment variable to call verifyIdToken().
该应用程序应该做的是检查服务器端以确定令牌是否有效。如下
export async function getServerSideProps(ctx) {
try {
const cookies = nookies.get(ctx);
const token = await verifyIdToken(cookies.token);
// the user is authenticated!
const { uid, email } = token;
return {
props: {
userData: {
email: email,
uid: uid,
},
},
};
} catch (err) {
console.log(err.code)
console.log(err.message)
return { props: {
} };
}
}
解决方案
auth/invalid-credential错误信息意味着需要初始化Admin SDK,我们可以在官方文档中看到。
用于验证 Admin SDK 的凭据不能用于执行所需的操作。某些身份验证方法(例如 createCustomToken() 和 verifyIdToken() )需要使用证书凭据而不是刷新令牌或应用程序默认凭据来初始化 SDK。
对于ID 令牌验证,需要项目 ID。Firebase Admin SDK 尝试通过以下方法之一获取项目 ID:
- 如果 SDK 使用显式 projectId app 选项初始化,则 SDK 使用该选项的值。
- 如果 SDK 是使用服务帐号凭据初始化的,则 SDK 使用服务帐号 JSON 对象的 project_id 字段。
- 如果设置了 GOOGLE_CLOUD_PROJECT 环境变量,SDK 会使用其值作为项目 ID。此环境变量可用于在 Google 基础架构(例如 App Engine 和 Compute Engine)上运行的代码。
因此,我们可以使用服务初始化 Admin SDK(并实现第二个选项);但是,首先要做的是验证服务帐户并授权它访问 Firebase 服务,您必须生成 JSON 格式的私钥文件。
要为您的服务帐户生成私钥文件,您可以执行以下操作:
- 在 Firebase 控制台中,打开设置 > 服务帐户。
- 单击 Generate New Private Key,然后单击 Generate Key 进行确认。
- 安全地存储包含密钥的 JSON 文件。
获得 JSON 文件后,您可以设置一个环境变量来保存您的私钥。
export GOOGLE_APPLICATION_CREDENTIALS="/home/user/Downloads/service-account-file.json"
然后,在您的代码中使用它,如下所示:
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: 'https://<DATABASE_NAME>.firebaseio.com'
});
推荐阅读
- javascript - 基于另一个值的 MVC 禁用字段(只读)
- javascript - 如何从 jquery 类访问多个数据到另一个输入字段以使用 python 提取
- html - 为什么我第一次打开页面时我的汉堡菜单会关闭?
- php - Wordpress 分页没有在页面上返回相同数量的帖子
- python - 检查数组以查找字典值中的匹配项并返回键
- objective-c - 苹果事件屏幕中的键盘 UI 问题
- apache-flink - Flink 丰富传入数据和处理时间
- python - 如何更改 pytest 类中参数化堆叠的顺序?
- php - 调用 SOAP 服务返回内部错误(来自服务器)
- python-3.x - Matplotlib 不保存图形所有带有轴的图形