Reputation: 292
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:
Created a default.json file:
{ "adminPassword": "" }
Created a custom-environment-variables.json file:
{ "adminPassword": "fifteen_adminPassword" }
Then I modified the code to this:
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
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:
~/.ssh/
directory which is only user readable). Please note that this is only a thin layer of safety, but it provides the most comfortUpvotes: 0
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:
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