使用sveltejs/adapter-auto部署到Firebase时getClientAddress报错,如何获取客户端IP?
问题:Firebase部署SvelteKit应用后
getClientAddress()报错 本地执行npm run dev时,获取客户端IP会返回本地地址(::1),但通过Firebase实验性Web框架功能部署到Firebase Hosting后,调用getClientAddress()会抛出错误:sveltejs/adapter-auto does not specify getClientAddress
完整错误日志:
Error: @sveltejs/adapter-auto does not specify getClientAddress. Please raise an issue at event.getClientAddress (file:///workspace/index.js:2507:13) at POST (file:///workspace/entries/endpoints/api/signin/_server.ts.js:13:42) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async render_endpoint (file:///workspace/index.js:221:20) at async resolve (file:///workspace/index.js:2740:22) at async respond (file:///workspace/index.js:2629:22) at async handle (file:///workspace/node_modules/firebase-frameworks/dist/sveltekit/index.js:13:22)
相关代码示例
端点代码
import { adminAuth, adminDB } from "$lib/server/admin"; import { error, json } from "@sveltejs/kit"; import type { RequestHandler } from "@sveltejs/kit"; import { LogEvent } from "$lib/components/LogEngine"; export const POST: RequestHandler = async ({ request, cookies, getClientAddress }) => { // token stuff here if (new Date().getTime() / 1000 - decodedIdToken.auth_time < 5 * 60) { // login stuff here await LogEvent(uid, "Logged in", getClientAddress(), "info"); return json({ status: "success" }); } else { // deal with errors } };
svelte.config.js配置
import adapter from '@sveltejs/adapter-auto'; import { vitePreprocess } from '@sveltejs/kit/vite'; /** @type {import('@sveltejs/kit').Config} */ const config = { preprocess: vitePreprocess(), kit: { adapter: adapter() } }; export default config;
当前使用Firebase实验性Web框架功能部署应用,除getClientAddress()外,默认适配器可正常工作。
解决方案
adapter-auto目前无法在Firebase Hosting环境下支持getClientAddress(),因为它是通用适配器,对Firebase的实验性Web框架支持尚未完善,因此会抛出该错误。不需要切换到第三方日志包,日志包不影响IP获取逻辑,可通过以下方式解决:
1. 从请求头手动提取客户端IP
Firebase Hosting会将客户端真实IP放在请求头的x-forwarded-for字段中,你可以直接从请求头获取:
// 替换原getClientAddress()的调用 const ipHeader = request.headers.get('x-forwarded-for'); const clientIp = ipHeader ? ipHeader.split(',')[0].trim() : 'unknown'; await LogEvent(uid, "Logged in", clientIp, "info");
注:x-forwarded-for可能包含多个IP(经过多层代理时),第一个值即为客户端真实IP。
2. 兼容本地开发与生产环境
本地开发时x-forwarded-for不存在,可做兼容处理,避免报错:
let clientIp: string; try { clientIp = getClientAddress(); } catch (e) { const ipHeader = request.headers.get('x-forwarded-for'); clientIp = ipHeader ? ipHeader.split(',')[0].trim() : 'unknown'; } await LogEvent(uid, "Logged in", clientIp, "info");
后续若adapter-auto更新完善了Firebase环境的getClientAddress()支持,可再切换回原方法。
内容的提问来源于stack exchange,提问作者mcy
相关产品推荐
相关产品推荐

