如何在SvelteKit中创建安全可复用函数?API令牌是否会暴露?
解决SvelteKit复用函数时避免API令牌暴露的方案
核心原则
所有涉及API令牌的敏感逻辑必须放在服务端专属模块中,绝对不能在客户端代码(如+page.svelte、普通utils.ts这类会被打包到前端的文件)里处理,防止令牌被暴露给浏览器。
具体实现步骤
迁移敏感复用函数到服务端目录
在项目lib/server/下创建专属文件(比如api-handlers.ts),把你之前写在utils.ts里的敏感函数移到这里,API令牌可以直接写在这里,或者通过SvelteKit的私有环境变量($env/static/private)读取:// lib/server/api-handlers.ts import { API_TOKEN } from '$env/static/private'; export async function reusableApiCall(data: Record<string, any>) { const res = await fetch('https://你的API地址', { method: 'POST', headers: { 'Authorization': `Bearer ${API_TOKEN}`, 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); return res.json(); }lib/server/目录下的文件只会在服务端运行,永远不会被编译发送到客户端,令牌完全安全。通过服务端入口调用复用函数
- 如果是页面加载时需要调用:在
+page.server.ts的load方法里调用这个函数,把结果传给前端页面
然后在// +page.server.ts import { reusableApiCall } from '$lib/server/api-handlers'; export async function load() { const apiData = await reusableApiCall({ /* 请求参数 */ }); return { apiData }; }+page.svelte里直接使用返回的数据:<script> export let data; </script> <div>{JSON.stringify(data.apiData)}</div> - 如果是用户交互(如点击按钮)时调用:创建一个
+server.ts路由作为中间层
再在// routes/api/invoke-function/+server.ts import { reusableApiCall } from '$lib/server/api-handlers'; import type { RequestHandler } from './$types'; export const POST: RequestHandler = async ({ request }) => { const reqData = await request.json(); const result = await reusableApiCall(reqData); return new Response(JSON.stringify(result), { headers: { 'Content-Type': 'application/json' } }); };+page.svelte里通过fetch调用这个服务端路由:<script> async function triggerApiCall() { const res = await fetch('/api/invoke-function', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ /* 用户输入的参数 */ }) }); const result = await res.json(); // 处理返回结果 } </script> <button on:click={triggerApiCall}>调用接口</button>
- 如果是页面加载时需要调用:在
拆分非敏感逻辑(可选)
如果你的复用函数里有不涉及令牌的通用逻辑(比如数据格式化),可以把这部分拆分到普通utils.ts里,敏感逻辑留在服务端模块:// utils.ts(客户端安全) export function formatRequestData(rawData: any) { return { ...rawData, timestamp: Date.now() }; } // lib/server/api-handlers.ts import { API_TOKEN } from '$env/static/private'; import { formatRequestData } from '$lib/utils'; export async function reusableApiCall(rawData: any) { const formattedData = formatRequestData(rawData); // 后续带令牌的请求逻辑... }
内容的提问来源于stack exchange,提问作者Boris Barroso
相关产品推荐
相关产品推荐

