admin管理员组

文章数量:1290186

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 .gitignored .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 in public/javascripts/src, and which are piled by gulp into public/javascripts/build/*.js.
  • I'm trying to access the key in a .js file in public/javascripts/ which is required by one of the .jsx files.
  • In that required .js file, process.env returns an empty object. When I try to access process.env in the .jsx files, I'm actually told that process 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 ining data?

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 .gitignored .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 in public/javascripts/src, and which are piled by gulp into public/javascripts/build/*.js.
  • I'm trying to access the key in a .js file in public/javascripts/ which is required by one of the .jsx files.
  • In that required .js file, process.env returns an empty object. When I try to access process.env in the .jsx files, I'm actually told that process 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 ining data?

Share Improve this question edited Oct 28, 2015 at 19:51 Sasha asked Oct 28, 2015 at 18:31 SashaSasha 6,46613 gold badges60 silver badges107 bronze badges 4
  • Just to clarify, you're requiring process.env in a file that is served to and executed in the browser? – Yuri Zarubin Commented Oct 28, 2015 at 18:36
  • Hmm. I guess. Does that make the API key fundamentally insecure? If I want to make this API call from a React file, how might I secure it? – Sasha Commented Oct 28, 2015 at 18:41
  • @Sasha what kind of Error do you receive from the code in the edited section ? – John Pink Commented Oct 28, 2015 at 20:09
  • I actually made this a separate question (stackoverflow./questions/28468084/…). I just received a 500. Can't find more details than that in my server logs or the console logs. (The error reporting, or lack thereof, that I've been able to find in node, is another issue entirely) – Sasha Commented Oct 28, 2015 at 20:11
Add a ment  | 

2 Answers 2

Reset to default 5

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 municate 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 municate with each other using global objects like process for example.

Your script in public/javascripts/, that is executed on the client's puter, 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 !

All .jsx is, is some code, what matters is where the code is being executed. process.env is a variable that is accessible inside the Node.js runtime. When your .jsx code gets transpiled down to .js and served to the browser, the process.env variable will no longer exist. If you're making an API call inside the browser, the API key will be fundamentally available to the client. If you want to secure the key, you have to have your Node.js server expose an API route, which your React app will hit. That Node.js server will then make the call to the external service using the API key. Because that call is being made by the server, process.env will be available, and will remain hidden from the client. You can then forward the result of the API call back to the user.

本文标签: javascriptNode processenv variables emptyStack Overflow