Problem
I have been using Firebase auth on my client. I am using firebase-admin
to verify on the server. It has been working great, but not I am migrating to another server and it just stopped working.
我一直在我的客户端上使用Firebase身份验证。我正在使用Firebase-admin在服务器上进行验证。它一直工作得很好,但不是我正在迁移到另一台服务器,它只是停止工作。
This is the important parts of the error message:
以下是错误消息的重要部分:
Error message
FirebaseAuthError: Error fetching public keys for Google certs: <!DOCTYPE html>
<p>Your client does not have permission to get URL <code>/robot/v1/metadata/x509/[email protected]</code> from this server. <ins>That’s all we know.</ins>\n'
Code
This occurs on 3 different new servers I have tried. It still works on the old server and when I use it locally.
这发生在我尝试过的3台不同的新服务器上。当我在本地使用它时,它仍然可以在旧服务器上运行。
I am ONLY using Firebase for auth, nothing else. On the server side, I'm using a service account like this:
我只是在使用Firebase进行身份验证,没有其他用途。在服务器端,我使用的服务帐户如下:
import { raise } from "@banjoanton/utils";
import { cert, initializeApp } from "firebase-admin/app";
import { getAuth } from "firebase-admin/auth";
import "dotenv/config";
const serviceAccount = {
key: process.env.FIREBASE_ADMIN_KEY ?? raise("FIREBASE_ADMIN_KEY missing"),
};
const firebaseBuffer = Buffer.from(serviceAccount.key, "base64");
const firebaseKey = firebaseBuffer.toString("utf8");
const app = initializeApp({
credential: cert(JSON.parse(firebaseKey)),
});
export const auth = getAuth(app);
This is the middleware the breaks:
这是BREAKS的中间件:
import { isDev } from "@app/utils";
import { raise } from "@banjoanton/utils";
import { DecodedIdToken } from "firebase-admin/auth";
import { auth } from "firebase-server";
import { Context, Next } from "hono";
import { UserRepository } from "server";
import { createLogger } from "utils";
const logger = createLogger("authMiddleware");
const allowedPaths: string[] = [];
export const authMiddleware = async (c: Context, next: Next) => {
const url = new URL(c.req.url);
if (allowedPaths.some(path => url.pathname.startsWith(path))) {
await next();
return;
}
if (isDev()) {
const uid = process.env.DEVELOPMENT_UID ?? raise("DEVELOPMENT_UID is not set");
c.set("userId", Number(uid));
await next();
return;
}
const authHeader = c.req.headers.get("Authorization");
if (!authHeader) {
logger.info("No auth header");
return new Response("Unauthorized", { status: 401 });
}
if (!authHeader?.startsWith("Bearer ")) {
logger.info("No bearer token");
return new Response("Unauthorized", { status: 401 });
}
const idToken = authHeader.split("Bearer ")[1];
if (!idToken) {
logger.info("No id token");
return new Response("Unauthorized", { status: 401 });
}
let decodedToken: DecodedIdToken;
try {
decodedToken = await auth.verifyIdToken(idToken);
} catch (error) {
console.log(error);
return new Response("Unauthorized", { status: 401 });
}
if (!decodedToken) {
logger.info("No decoded token");
return new Response("Unauthorized", { status: 401 });
}
const userIdResponse = await UserRepository.getIdByExternalId(decodedToken.uid);
if (!userIdResponse.success) {
logger.info("No user id in database, creating user");
const externalId = decodedToken.uid;
const email = decodedToken.email;
const name = decodedToken.name;
if (!externalId || !email || !name) {
logger.error("No externalId, email or name in decoded token");
return new Response("Unauthorized", { status: 401 });
}
const user = await UserRepository.createUser({
externalId,
email,
name,
});
if (!user.success) {
logger.error("Could not create user");
return new Response("Unauthorized", { status: 401 });
}
logger.info("Created user with id: ", user.data.id);
c.set("userId", user.data.id);
await next();
return;
}
c.set("userId", userIdResponse.data);
await next();
};
And once again, it works perfectly on the old server and locally, just not on any new server I have tried. This is the culprit:
再一次,它在旧服务器和本地服务器上都能完美地工作,只是不能在我尝试过的任何新服务器上工作。这就是罪魁祸首:
decodedToken = await auth.verifyIdToken(idToken);
Basically, I'm not sure why it does not work. Do I need to update some setting or something in the Google Service Account?
基本上,我不确定它为什么不起作用。我是否需要更新Google服务帐户中的某些设置或其他内容?
Some other things:
其他一些事情:
- Hosted on Hetzner in Germany and Finland
- Using Caprover
- Tried creating a completely new Firebase project but could not make that work either
更多回答
我是一名优秀的程序员,十分优秀!