You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用环境变量密钥通过Axios获取数据并保障密钥安全

问题分析与解决方案

核心问题原因

  1. 客户端无法读取未暴露的环境变量:你的updateUser.js是客户端组件(useEffect属于客户端执行代码),Next.js默认仅会将带NEXT_PUBLIC_前缀的环境变量暴露给客户端,因此process.env.LOCAL_API_KEY在这里实际是undefined,导致传给后端的密钥参数为空,触发401验证失败。
  2. 密钥传递方式不安全:即使你给环境变量加上NEXT_PUBLIC_前缀,将密钥放在URL参数中也会直接暴露在浏览器地址栏、服务器日志、请求历史里,存在严重的泄露风险。

正确实现方案

方案一:利用用户会话替代API密钥验证(推荐)

既然你已经在用useSession(推测是NextAuth.js),直接通过会话验证用户身份,确保当前请求的用户只能访问自己的数据,完全不需要额外传递密钥:

修改后端API路由 [id].js
import db from "@/database/connect"
import Users from "@/database/modals/users"
import { getServerSession } from "next-auth/next"
import { authOptions } from "../auth/[...nextauth]" // 导入你的NextAuth配置文件

export default async function handler(req, res){
    const session = await getServerSession(req, res, authOptions)
    const { id } = req.query

    // 验证会话有效性,且请求的用户ID与当前登录用户ID一致
    if (!session || session.user._id !== id) {
        return res.status(401).json({ error: 'Unauthorized User..' })
    }

    if (req.method === 'GET') {
        try{
            await db.connect()
            const userInfo = await Users.findById(id)
            await db.disconnect()
            
            if(userInfo){
                // 在后端直接过滤敏感字段,避免前端接触敏感数据
                const { password, admin, ...safeUser } = userInfo.toObject()
                return res.status(200).json({ user: safeUser })
            }else{
                return res.status(404).json({ error: 'User not found' })
            }   
        }catch(err){
            return res.status(500).json({ error: 'Failed to fetch user data' })
        }
    }else{
        return res.status(405).json({ error: 'ONLY GET REQUESTS ARE ALLOWED' })
    }
}
修改前端 updateUser.js
const { data: session } = useSession()
useEffect(() => {
    if(session){
        const checkUserInfo = async() => {
            try{
                const fetchUserInfo = await axios.get(`/api/users/${session.user?._id}`)
                localStorage.setItem('userSession', JSON.stringify(fetchUserInfo.data.user))
            }catch(err){ 
                console.log(err)
                localStorage.removeItem('userSession')
            }
        }
        checkUserInfo()  
    }else{
        localStorage.removeItem('userSession')
    }
}, [session])

方案二:若需调用第三方Middleware API(后端持有密钥)

如果你的需求是通过自己的API路由调用第三方Middleware API,密钥应该仅在后端存储和使用,前端无需知晓:

import db from "@/database/connect"
import Users from "@/database/modals/users"
import { getServerSession } from "next-auth/next"
import { authOptions } from "../auth/[...nextauth]"
import axios from "axios"

export default async function handler(req, res){
    const session = await getServerSession(req, res, authOptions)
    const { id } = req.query

    if (!session || session.user._id !== id) {
        return res.status(401).json({ error: 'Unauthorized User..' })
    }

    if (req.method === 'GET') {
        try{
            // 后端调用第三方Middleware API,将密钥放在请求头中
            const middlewareRes = await axios.get(`https://your-middleware-api.com/users/${id}`, {
                headers: {
                    'X-API-Key': process.env.LOCAL_API_KEY // 按第三方要求的头格式传递
                }
            })

            const { password, admin, ...safeUser } = middlewareRes.data.user
            return res.status(200).json({ user: safeUser })
        }catch(err){
            return res.status(500).json({ error: 'Failed to fetch from middleware API' })
        }
    }else{
        return res.status(405).json({ error: 'ONLY GET REQUESTS ARE ALLOWED' })
    }
}

关键安全注意事项

  • 敏感密钥绝不暴露给客户端:客户端代码会被用户完全解析,任何放在前端的密钥都会直接泄露。
  • 优先使用会话验证:针对自有API,用户会话(如NextAuth)是最安全的身份验证方式,能精准控制数据访问权限。
  • 密钥传递用请求头:若必须传递密钥(如第三方API),使用Authorization或自定义X-API-Key请求头,禁止放在URL参数或请求体中。
  • 环境变量规范:Next.js中仅NEXT_PUBLIC_前缀的变量会暴露给客户端,敏感变量不要加该前缀,仅在后端使用。

内容的提问来源于stack exchange,提问作者Viper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:53:10