next.js 如何使用环境密钥与Axios获取

disbfnqx  于 2023-03-29  发布在  iOS
关注(0)|答案(2)|浏览(173)

我正在尝试从中间件API获取数据,并使用密钥来保护API。
但是当我尝试获取数据时,它无法识别Secret参数,
我怎样才能使它获取数据并使我的密钥Secret

.环境.本地

LOCAL_API_KEY=5b45f6898634abf9c3769b763c5fa8ddfc57d2cc943a0601f7bda4269ebe7342

updateUser.js

const {data: session} = useSession()
    useEffect(() => {
        if(session){
            const checkUserInfo = async() => {
                try{
                    const fetchUserInfo = await axios.get(`/api/users/${session.user?._id}`,{
                        params: {
                            API_ROUTE_SECRET: process.env.LOCAL_API_KEY
                        }
                    })
                    console.log(fetchUserInfo) //  Output: Code 401
                    delete fetchUserInfo.data.user.password 
                    delete fetchUserInfo.data.user.admin
                    fetchUserInfo.data.user && localStorage.setItem('userSession', JSON.stringify(fetchUserInfo.data.user))
                }catch(err){ 
                    console.log(err)
                }
            }
            checkUserInfo()  
        }else{
            localStorage.removeItem('userSession')
        }
    }, [session])

[id].js

import db from "@/database/connect"
import Users from "@/database/modals/users"

export default async function handler(req, res){
    const {id, API_ROUTE_SECRET} = req.query
    console.log('key', API_ROUTE_SECRET) // Output: undefiend
    if(API_ROUTE_SECRET !== process.env.LOCAL_API_KEY){
        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){
                res.status(201).json({user: userInfo})
            }else{
                res.status(404).json({error: 'User not found'})
            }   
        }catch(err){
            res.status(404).json({error: 'No Data For This User'})
        }
    }else{
        res.status(500).json({error: 'ONLY GET REQUESTS ARE ALLOWED'})
    }
}
bvjxkvbb

bvjxkvbb1#

axios.get接受请求配置作为第二个参数(不是查询字符串参数)。
您可以使用params config选项设置查询字符串参数,如下所示:

const fetchUserInfo = await axios.get(`/api/users/${session.user?._id}`, {
  params: {
    API_ROUTE_SECRET: process.env.LOCAL_API_KEY,
  },
});
mm9b1k5b

mm9b1k5b2#

警告:

不要在你的React应用中存储任何秘密(比如API私钥)!
环境变量嵌入到构建中,这意味着任何人都可以通过检查应用的文件来查看它们。

溶液

在env变量前加上REACT_

REACT_LOCAL_API_KEY=*****

和使用它

process.env.REACT_LOCAL_API_KEY

CSR SPA变量

不管你是在使用react,vue还是angular,问题都是一样的:CSR应用程序只是浏览器中加载的JavaScript,因此出于安全原因,JavaScript无法读取用户机器的env变量。
只允许服务器应用程序读取机器的env变量。

Build vs Runtime

默认情况下,在所有知名的框架(react,vue或angular)中,变量都是在构建时硬编码的,而不是在运行时。所以如果你想有几个阶段(test,uat,prod等),你需要为每个阶段构建。
在运行时(Web浏览器,而不是你的开发IDE),你的js应用程序只使用全局变量,这些变量是在构建时插入的env变量的模拟:

process.env.FOO

process.env是在服务器层读取env变量的唯一选项。

一些框架,如react,创建了一个模拟,并将其公开为全局var,以便于使用:

但由于这是一个模拟,为了避免暴露所有环境变量(构建或开发人员机器),react将只暴露前缀为:React_

一次构建

如果你理解为每个阶段构建的复杂性,而不是像服务器应用程序那样只构建一个,你可以使用我的策略:
https://jrichardsz.github.io/devops/just-one-build-for-spas
基本上,你应该在为你的前端服务的服务器中公开一个/设置(react,angular,vue)。
然后改为使用框架选项

  • React:process.env.REACT-FOO
  • Angular:../environments/environment

使用/设置,结果将其公开为全局变量。
有了这个,您将拥有一个能够在任何阶段部署的前端构建,因为它在构建时没有硬编码值
您可以使用我的水疗服务器,它提供以下功能:
https://github.com/usil/nodeboot-spa-server

相关问题