Gilbert R.
Gilbert R.

Reputation: 292

Storing a password in an environment variable using Node.js

I am creating administrator credentials for my application. The model is quite simple; it has username and password properties and some validation as well. I have a function where I populate some information in the database.

async function init() {
  const admin = new Admin({
    username: "admin",
    password: "12345"
  });

  const salt = await bcrypt.genSalt(10);
  admin.password = await bcrypt.hash(admin.password, salt);

  try {
    await admin.save({ username: admin.username });
  } catch (ex) {
    console.log(ex.message);
  }
}

However, with this approach I am saving the password in my source code, and I don't want that. I was thinking that maybe I could store my administrator password in an environment variable using the config package.

I tried the following:

const admin = new Admin({ username: "admin", password: config.get("adminPassword") });

Finally I set the environment variable export fifteen_adminPassword=12345, but this fails as invalid password when I'm authenticating.

Upvotes: 0

Views: 13092

Answers (2)

user826955
user826955

Reputation: 3206

You are already hashing the password, so you don't need it any more as clear text.

Just store the hashed password in your code (which might not be so great, since it’s inflexible) or in some configuration file. I don't see what benefit environment variables would bring over having the password in your code, other than introducing more risks.

If your application needs credentials to log into whatever service, and you cannot keep password hashes (e.g., because you need to log in using the real password), then the clear-text password needs to be stored. If you're designing the user management and are in control of the login mechanism, you most likely do not need to store clear text passwords, but it can instead store hashes and use those for login.

In case you still want to store clear text passwords, you should try to store them in a safe location (environment variables are not a safe location).

You could:

  • Store passwords in password managers or a safe locations (e.g., iOS keychain)
  • Encrypt passwords with a passphrase which is entered whenever your application starts, and then save the encrypted passwords in some configuration file of your app
  • Encrypt passwords with a passphrase which in turn is stored in a safe location (e.g., the ~/.ssh/ directory which is only user readable). Please note that this is only a thin layer of safety, but it provides the most comfort

Upvotes: 0

Yilmaz
Yilmaz

Reputation: 49293

I used the config package before, but I got too much headache. So I switched to the env-cmd package. Here is how you should implement it:

npm install env-cmd

Then create a /config directory in your root folder. Create a dev.env file inside of it. Enter your variables here like this:

File /config/dev.env

PORT=3000
ADMIN_PASSWORD=fifteeen_adminpassword

Note that for the naming convention, environment variables are always capital letters and we separate them by "_". And values are not strings.

Now you need to configure the package.json file. In directory "scripts", we usually have start, dev, and test scripts. Start is for deployment platforms, test for testing and dev for our current development environment. If you are using nodemon (most likely you are) your dev scripts should like this:

"scripts": {
    "start": "node src/index.js",
    "dev": "nodemon src/index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

When you run npm run dev, the terminal will run this nodemon src/index.js. This is a basic configuration for any Node.js application. Now we need to pass our variables that are stored in /config/dev.env to our application. For this, change "dev" to:

"dev": "env-cmd -f ./config/dev.env nodemon src/index.js",

Now the env-cmd package set all the variables that you passed to /config/dev.env as environment variable. Now you use them like this:

const admin = new Admin({
        username: "admin",
        password: process.env.ADMIN_PASSWORD
      });

Note that when you deploy your project to GitHub, you have add the configuration folder name to the .gitignore file. So your passwords or API keys are not going to be public.

Also every time you add a new variable to the dev.env file, kill the terminal process and restart it. MongoDB will give an error.

Upvotes: 4

Related Questions