Nuxt3项目调用第三方API时如何保护x-api-key并解决CORS问题
一、保护X-API-Key的核心原则
永远不要在客户端代码(如组件、客户端composables)中直接暴露API密钥,必须通过服务器端代码处理密钥的传递——浏览器会暴露所有客户端代码,直接放置密钥会导致泄露。
具体实现方法
用Runtime Config存储密钥
在项目根目录创建.env文件,添加密钥:NUXT_API_KEY=your_actual_api_key_here然后在
nuxt.config.ts中配置runtime config,确保密钥仅在服务器端可访问:export default defineNuxtConfig({ runtimeConfig: { apiKey: process.env.NUXT_API_KEY, // 仅服务器端可见 public: { // 此处放客户端可访问的公开配置,不要包含密钥 } } })创建服务器端代理路由
在server/api/目录下新建文件(如fetch-third-party-data.ts),在服务器端处理第三方API调用:export default defineEventHandler(async (event) => { const { apiKey } = useRuntimeConfig() const response = await fetch('https://third-party-api.com/your-endpoint', { method: 'GET', // 或对应请求方法 headers: { 'X-API-Key': apiKey } }) if (!response.ok) { throw createError({ statusCode: response.status, statusMessage: response.statusText }) } return await response.json() })客户端只需调用本地API即可获取数据,无需接触密钥:
<script setup> const { data: apiData } = await useFetch('/api/fetch-third-party-data') </script>Server-Only Composables
若需在组件中直接调用逻辑,可创建仅在服务器端执行的composable(composables/useThirdPartyData.ts):export const useThirdPartyData = async () => { const { apiKey } = useRuntimeConfig() const response = await fetch('https://third-party-api.com/your-endpoint', { headers: { 'X-API-Key': apiKey } }) return await response.json() }在组件中使用时,Nuxt会自动将该调用放在服务器端执行(SSR模式下),不会暴露密钥到客户端:
<script setup> const data = await useThirdPartyData() </script>
二、解决CORS错误
Postman能正常请求是因为它不受浏览器同源策略限制,而浏览器会拦截跨域请求。解决方法如下:
利用服务器端代理路由(推荐)
上述的服务器端代理路由天然解决CORS问题:客户端请求的是同域名的/api/xxx接口,服务器端再转发请求到第三方API,服务器端请求不受同源策略限制。配置Nuxt代理模块
若不想手动编写服务器路由,可使用@nuxtjs/proxy模块:- 安装依赖:
npm install @nuxtjs/proxy - 在
nuxt.config.ts中配置:export default defineNuxtConfig({ modules: ['@nuxtjs/proxy'], proxy: { '/api/proxy': { target: 'https://third-party-api.com', changeOrigin: true, pathRewrite: { '^/api/proxy': '' }, headers: { 'X-API-Key': process.env.NUXT_API_KEY } } }, runtimeConfig: { apiKey: process.env.NUXT_API_KEY } })
客户端请求
/api/proxy/your-endpoint即可,代理会自动转发请求并带上密钥。- 安装依赖:
请求API提供者配置CORS白名单
如果第三方API支持自定义CORS规则,可将你的项目域名提交给API提供者,让他们将域名加入允许列表。但即使如此,仍需通过服务器端传递密钥,不能在客户端直接暴露。
内容的提问来源于stack exchange,提问作者Oliver Jacob

