问题描述
我正在构建我的第一个Express应用程序,它需要与API进行交互,使用一个非常安全的API密钥。所以我想遵循保持密钥(和任何未来的环境变量)的基本模式,在一个 .gitignore
d .env
文件在根目录下。
为了不重塑轮子,我使用了,并在我的 app.coffee
文件(应用程序的根文件)中设置我的env变量:
env = require('node-env-file')
env __dirname +'/.env'
console.log process.env.MY_API_KEY
那个 console.log
打印出正确的键到服务器日志。问题出现在后面:
如果我尝试在我的应用程序稍后加载的一个JS文件中访问相同的变量, process.env
是一个空对象,因此API密钥是 undefined
。这不会出现是上述程序包的一个问题,因为如果我在CL( API_KEY =任何npm开始
)中定义变量, ,行为是一样的 - 它控制台从 app.coffee
正确记录,但稍后不可用。
有关如何无法使用密钥的文件的一些信息正在加载:
- 该应用正在运行React,它写在
public / javascripts / src
中的几个.jsx
文件中,并且由gulp
编译成public / javascripts / build / *。js
。 - 我试图访问
.js
文件中的public / javascripts / code>其中
要由
d。.jsx
文件之一 - 在需要的
.js
文件中,process.env
返回一个空目的。当我尝试访问.jsx
文件中的process.env
时,实际上被告知进程
本身未定义。
任何想法,这里发生了什么?我是新来的Express / React,并且不清楚这个进程
对象,我认为是全局的,并且定义在 npm开始
被定义,所有的 env
信息正在发生。
谢谢!如果有任何其他信息将有所帮助,请告知我,否则任何人有任何建议,在我的情况下,如何更好地处理私人 env
信息。
编辑:
我尝试了以下建议,并创建了一个单独的端点在内部,它触及外部API,然后返回响应。我正确地纠正了一些事情,以便正确响应:
router.get'/ images',(req,res ,下一个) - >
res.json({some:'json'});
但这个(它使用一个单独的类来请求一个外部API),会引发错误:
router.get'/ images',(req,res,next) - >
new Images('nature')。fetch(images) - >
res.json({some:'json'})
本质上来说,来自外部API的响应的异步(甚至不被忽略的数据本身)正在创建一个问题。如何打到这个外部端点,然后使用传入的数据响应内部请求?
后端vs前端 - 结束
您似乎试图从前端位置以错误的方式访问后端数据。
Node.js的强大功能是在前面和后面都有JavaScript,但是从头开始就明白每个脚本在哪一边执行的时候,这是相当混乱的。
在Express项目中,发送到前端的所有Javascript文件将直接与客户页面进行交互,位于公共/ Javascript角/
。一般来说,您将在其中一些文件中具有一些AJAX功能来交换数据并与后端进行通信。
这些后端文件位于其他位置:在根目录, routes /
以及您创建的所有其他文件夹。这些文件几乎全部连接到您的Node实例,因此可以使用全局对象(例如 process
)进行通信。
在客户端计算机上执行的 public / javascripts /
中的脚本正在尝试直接访问运行Node实例的服务器上的变量:这就是为什么你的代码不起作用如果您希望从后端访问数据,则必须在前端使用AJAX调用。
服务器& ---(仅限AJAX)---客户端
------ ------
app.js public / javascripts / script.js
routes.js
...
就是说,你想保持你的API密钥是私有的,不会如果您将其发送给在该特定页面上的每个客户端都会发生。您应该做的是使用例如 xhr
模块从后端进行呼叫,然后将数据传递到前端,而不使用秘密API密钥。
我希望我很清楚,Node起初很混乱,但很快就会得到这些小错误!
I'm building my first Express app, which needs to interact with an API, using an API key that ideally remains secure.
So I wanted to follow a basic pattern of keeping the key (and any future environment variables), in a .gitignore
d .env
file in the root directory.
To not reinvent the wheel, I used this package, and set my env variables like so, in my app.coffee
file (the root file of the application):
env = require('node-env-file')
env __dirname + '/.env'
console.log process.env.MY_API_KEY
That console.log
prints out the right key to the server logs. The problem arises later:
If I try to access that same variable in one of the JS files loaded later on by my app, process.env
is an empty object, so the API key is undefined
. This doesn't appear to be a problem with the above package, because if I define the variable in the CL (API_KEY=whatever npm start
), the behavior is the same -- it console logs correctly from app.coffee
but is unavailable later.
Some information on how the files in which the key is unavailable are being loaded:
- The app is running React, which I write to a few
.jsx
files inpublic/javascripts/src
, and which are compiled bygulp
intopublic/javascripts/build/*.js
. - I'm trying to access the key in a
.js
file inpublic/javascripts/
which isrequire
d by one of the.jsx
files. - In that required
.js
file,process.env
returns an empty object. When I try to accessprocess.env
in the.jsx
files, I'm actually told thatprocess
itself is undefined.
Any ideas what's going on here? I'm new to Express/React, and unclear where this process
object, which I thought was global and defined on npm start
is defined, and what's happening to all the env
info in it.
Thanks! Please let me know if any other information would be helpful, orif anyone has any suggestions for how better to handle private env
info in my situation.
EDIT:
I tried the suggestions below, and created a separate endpoint internally, which hits the external API and then returns a response. I've strung things up correctly, so that this responds correctly:
router.get '/images', (req, res, next) ->
res.json({ some: 'json' });
but this (which uses a separate class to make a request to an external API), throws an error:
router.get '/images', (req, res, next) ->
new Images('nature').fetch (images) ->
res.json({ some: 'json' })
Essentially, it looks like the asynchrony of the response from the external API (and not even the data itself, which I ignored), is creating a problem. How do I hit this external endpoint and then respond to the internal request with the incoming data?
Back-end vs Front-end
It seems like you are trying to access back-end data from a front-end location, in a wrong way.The great power of Node.js is having JavaScript in the front and in the back, but it is quite confusing in the beginning to understand on which side each script is executed.
In an Express project, all Javascript files that are sent to the front-end, those that will directly interact with the client's page, are located in public/javascripts/
. Generally you will have some AJAX functions in some of those files to exchange data and communicate with the back-end.
These back-end files are located everywhere else : in the root directory, in routes/
, and all the other folders you create. Those files are pretty much all connected to your Node instance, and therefore can communicate with each other using global objects like process
for example.
Your script in public/javascripts/
, that is executed on the client's computer, is trying to directly access a variable located on the server running your Node instance : that's why your code doesn't work. If you wish to access data from the back-end, you must use AJAX calls in the front-end.
Server <---(AJAX only)--- Client
------ ------
app.js public/javascripts/script.js
routes.js
...
That being said, you wanted to keep your API key private, which will not happen if you send it to every client who's on that specific page. What you should do is make the call from the back-end, using the xhr
module for example, and then delivering the data to front-end, without the secret API key.
I hope I was clear, Node is quite confusing at first but very soon you will get over these little mistakes !
这篇关于Node process.env变量为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!