I’m trying to fetch data from the Middleware API and am using A secret key to Secure the API.
But when I try to fetch the data it just doesn’t recognize the Secret params,
How can I make it fetch the data and make my secret key Secret.
.env.local
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'})
}
}
2
Answers
axios.get accepts a request config as the second parameter (not query string params).
You can use the params config option to set query string params as follows:
WARNING:
Do not store any secrets (such as private API keys) in your React app!
Environment variables are embedded into the build, meaning anyone can view them by inspecting your app’s files.
Solution
Prefix your env variables with REACT_
and the use it with
CSR SPA variables
No matter if you are working with react, vue o angular, the problem is the same: CSR applications are just javascript loaded in the browser, so for security reasons, the javascript cannot read env variables of the user machine.
Only server applications are allowed to read env variables of machine.
Build vs Runtime
By default, in all the well known frameworks (react, vue o angular) variables are hardcoded on any build, not at runtime. So if you want to have several stages(test, uat, prod, etc) you will need to build for each stage.
At runtime (web browser, not your development IDE) , your js application only plays with global variables which are an emulation of the env variables inserted at build time:
process.env.FOO
process.env are the only option to read env variables at server layer.
Some frameworks like react , creates an emulation of this and expose it as global var to be easy the usage:
But since this is an emulation, to avoid the expose of all the environment variables (build or developer machine), react will only expose variables prefixed with: REACT_
Just one build
If you understood the complications of to build for each stage, instead just one build like server applications, you could use my strategy:
https://jrichardsz.github.io/devops/just-one-build-for-spas
Basically, you should expose a /settings in the server which is serving your frontend (react, angular , vue).
Then instead to use the framework options
Consume the /settings and the result expose it as global variables.
With this you will have one frontend build capable to be deployed on any stage because it don’t have hardcoded values at build time
You could use my spa server which offer this feature:
https://github.com/usil/nodeboot-spa-server