In this lesson you're going to learn how to set up custom environment variables for your node j s applications.
Now our application is actually already using an environment variable inside of index dot J S we access
process dot e envy.
This is where environment variables are stored and we access the port environment variable which is
provided by Heroku.
When Heroku runs our node application what we're going to focus on in this video is providing environment
variables to our node application.
But when it runs locally on our machine now there are two major reasons why using environment variables
is super important.
The first has to do with security and the second has to do with customize ability.
Well let's get started by talking about customization and to do that.
We're going to open up Mongoose and J.S. in the DB directory inside of here.
We have our database you are all hard coded into the application.
That means when we run the app locally it connects to our local database and so far that's been going
really well but it also means that when we deploy to Heroku it's still going to try to connect to our
local database which is not going to exist when we deploy to Heroku.
We'll be using another service to set up a professional Mongo DB database and we'll be using that connection
string on production.
So we have one value we want to provide when running and development and another value we want to provide
when running in production.
The answer is to set up an environment variable and provide different values for it when running and
development and production.
So without environment variables we would have no way to customize the connection string we're passing
to the Connect method based off of the environment we're running in where we have Dev locally on our
machine and proud or production on the Heroku servers.
Now when it comes to security we also get a lot of advantages when using environment variables.
So as an example right now we have a lot of important information hardcoded into our application such
as the API key for setting a grid over an account.
Dot J S now if we were to leave this right here in the javascript file we would eventually commit this
to get push it up to get hub and push it up to Heroku.
Now if everything goes well this API key won't fall into the wrong hands but merely by adding it to
our code we are increasing the chances that at some point either now or in the future someone gets access
to it.
So let me give you an example my friend just started to learn how to write software and this is a true
story.
Now we create a discord server for me and my friend group.
It's a little group chat and he was creating a chat bot for that as one of the first real projects he
built with node and JavaScript.
Now he created the application by getting an API key from our Dischord chat and using it to build the
bot.
So he built the bot with a private get Hub Repository and then he wanted to share it with the world.
So he went ahead and made that repo public.
Now before he did he removed the key switching to environment variables.
He committed that and he pushed it up thinking he was safe when he made the repo public though you've
got to remember that old commit history.
It's still there and it's still contained.
The discord API key someone somewhere wrote a bot that scrapes them and they held our discord chat ransom
asking for one hundred bitcoins.
Now obviously we didn't pay that.
We just went ahead and created a new chat from scratch and we took security a bit more seriously.
So when we have api keys in our code it's not necessarily dangerous but it leaves us open to more vulnerabilities
in the future.
So we're also going to break these out into environment variables and where those environment variables
are defined.
That's not going to get committed to the repository.
So there's zero chance they ever fall into the wrong hands.
Let's go ahead and figure out how we can get this done and we're going to start with the simplest example
in index dot J s what we want to do is provide our own environment variable value for port when it runs
locally on our machine.
So we don't have to hard code the port three thousand right here.
The first thing we're going to do is define that separate place for our environment variables and we're
going to put that in a new directory in the task manager app.
So right here we're going to create a config folder.
Now the config folder and its contents are gonna be ignored by get using a dot get ignore file much
like we did for the node modules directory when we created the web server app our weather application.
So right here in the new config folder we're going to add a single file for the moment and we'll call
it Dev dot EMV.
So this is where we're going to provide the environment variables for that dev environment.
And it is a file consisting of key value pairs one on each line.
So right here I could have key equals value where I'm now creating a key environment variable with the
value value in our case that's not what we want.
We want to set a value for port.
And I'm going to set it equal to the value three thousand which is what we're using locally in development.
Now it's important to make sure not to add any extra formatting including spaces in between the various
characters as that is going to affect how the environment variables are set.
You want in your file to look exactly like this one now from here.
That means we won't need to have three thousand right here.
We can remove it in the port environment variable is already provided by Heroku.
We've seen that and now our application locally is going to provide that as well.
Now currently it doesn't.
We have the environment file created but down below we can see that we're getting undefined as the value
for the port from our message right here.
Let's go ahead and adjust that.
But actually using that Dev dot EMV file to populate the environment variables for our node application
now setting environment variables is typically a huge pain because each operating system has a different
way to get that done.
We're going to use an NPM module though that allows us to get this done in a cross OS compatible way
which means your project will work on Windows Mac Linux and Linux distributions.
The module we're going to be using we can find over in the browser by googling NPM space EMV hyphen
S.M. D.
This NPM module is going to load in the environment variables we defined in that EMV file and then it's
going to make sure they're available to our node j s application and we're going to go ahead and set
this up in our project.
So over inside a visual studio code we want to install this module down below I'll use control C to
shut down node man followed by npm install the module is EMV hyphen it CMG at eight point zero point
two and this is a module we only need it locally on our machine it's not something we're going to need
on Heroku so we can use these save Dev flag like we did when we installed node on several sections a
go what I'm going to do is go ahead and run that installation command and then we're gonna head over
to package dot Jason as using this module requires us to make a small change to our script so over here
we have the Jason File and down below I can see that EMV BMD is installed as a dev dependency which
is great up above it's now our job to tell EMV CMT to load in the environment variables and provide
them to our project when using the dev script we're not going to do that for these start script as these
start script is going to run on Heroku and we'll talk about how we set environment variables on Heroku
in the next lesson for now all we need to do is make a small change to the Devon script we're gonna
add some stuff right up front so we'll leave these same command we had before just adding a space and
right here we're going to use EMV CMT as a command and that's provided by the tool we just installed
the next thing we provide is the path to the environment variable file.
We want to use.
Now for us that is dot forward slash config.
Forward slash Dev dot EMV.
That is the file that we created.
And with this in place we're now done.
So now when we run the def command EMV CMT is going to grab all of those environment variables.
Then it's going to continue to run the node application but it will provide those environment variables
to the app as it's running.
Now the end result is that I should no longer see undefined in the message server is up on port I should
actually see the value I defined over here.
Now let's switch things up and change this to three thousand and one so we can actually see the change
down below.
All I'm going to do is start up the app exactly like I've done dozens of times before NPM run Dev that's
going to load in those environment variables provide them to the node process and down below we can
see it's working as expected no demand is still running.
We can see it's output right here and we do indeed have the environment variable value.
Now if I were to change that value it's not going to automatically be detected EMV CND only runs once
right away.
Which means that we just need to restart our program whenever we change an environment variable.
And the good news is that once they're set we're almost never gonna change them right here.
I've tweaked it back to three thousand down below I'll use controls C to shut it down up and enter to
rerun the last command and this time I would expect to see port three thousand showing up and that is
exactly what I get.
So there we go.
That's how we can set environment variables for our application when we're just running locally on our
machine.
Now we're going to do the same thing for the Jason Webb token secret d send a grid API key and the Mongo
D.B. connection string.
Let's go ahead and work through one more together then there'll be a challenge for you to do a couple
on your own.
The one we're going to work through together is the send grid API key.
So right here we have the API key hardcoded into the javascript file.
That is not what we want.
I'm going to copy that to the clipboard and we're going to remove this line entirely instead of getting
the variable value from the variable we just had we will instead get it from an environment variable
which means that right here we'll be accessing process dot EMV dot something.
Now we can pick whatever name we would like for this one.
Let's go ahead and use something specific like send grid underscore API underscore key.
So a naming environment variables.
It's common to use all uppercase and to separate the words with underscores.
It's not required it's just a convention.
You don't have to follow it but it's a good idea to.
Now we are relying on this VI environment variable to exist it currently does not.
Let's go ahead and save the program and fix that by defining it over in dev dot EMV right here on the
next line that is send grid underscore API underscore key exactly like we defined it before and we're
setting that equal to the value I copied to the clipboard making sure that those quotes are not included
here we just have the API key itself.
Now I can save all of the files and down below I can manually restart the server and the API key should
still be set correctly and I should be able to still get emails.
Let's go ahead and test that out over in post man.
The last thing I did was delete the user a couple of videos ago.
Let's go ahead and recreate them once again using an email that I actually have access to so we can
make sure we get it in our inbox right here.
I'll go ahead and send that off down below the new user is created.
We can move over to Gmail and see what we get right over here in my inbox.
I have nothing.
Now as mentioned there's a decent chance these emails will end up in your spam folder until you configure
the custom domain.
And here it is.
Thanks for joining in and I have my message showing up and this is the one from zero minutes ago.
The one I just sent.
So the good news here is that the API Key is still being set up correctly and we're still able to send
emails even though it's defined over here.
Now it's your challenge you're going to be doing something similar for the Jason web token secret and
for the Mongo D.B. connection string.
Down below I have a series of comments outlining what I'd like you to do right here what I'd like you
to do is pull out the Jason web tokens secret and database you are all into environment variables defined
in this file and there are a few steps for getting this done.
First up create those two variables and set the values correctly.
You can just copy the existing value for each write out of the code.
Much like we copy to ah send grid API key from the code that was up above.
Then you're going to set up the values in the development EMV file that we have created and worked with
over here.
And finally in the code you want to swap out those hardcoded values for references to environment variables
just like we did right here on line three last up.
Test your work.
So if you're changing the JWT secret any database you are you could test both of those by creating a
new user and getting their profile.
If I'm able to get the profile that I know I can communicate with the database correctly and if my Jason
web token works when I sign up and then use it I know that's set correctly as well.
All right knock that out.
Test your work when you're done come back and click play.
How that go.
Let's go ahead and kick things off with the Mongo D.B..
You are real.
Then we'll do the JWT secret.
So right here inside of Mongoose Jay asked we have the connection string.
We want to use in our development environment.
I'm going to copy that to the clipboard head over to Dev dot EMV and create the new environment variable
that is Mongo D.B. underscore.
You are all setting and equal to the value I just copy it to the clipboard.
Next up inside a mongoose dot J S we're going to remove the hardcoded value and reference the environment
variable instead.
That's process dot EMV dot Mongo D.B. underscore.
You are all matching up exactly with what we had sitting right over here.
Now if I save the program you can see that things are crashing because there is no value provided yet.
I have to restart the server for the new end variables to be picked up.
We'll go ahead and do that in just a second.
Let's go ahead and knock out the other one first.
So over inside of the challenge comments we've taken care of Mongo D.B. for these three steps.
Let's do the same thing for the JWT secret.
Now we use that in a couple of different places.
We use it once in our authentication middleware to verify the token.
That's right here.
And we use it again inside of the User model when the token is created over in that file down below
we have the same value right here.
So let's go ahead and work through this process over in dev dot EMV.
I will create JWT underscore secret and we can pick whatever value we would like.
This is a secret for my app.
Perfect.
Now all we're going to do is swap it out with the hardcoded values in those two locations.
So right here for the user model we remove this string and we reference a process dot EMV dot JWT underscore
secret we save the program and we do the exact same thing in the off file when we verify that token
later on right here.
A process dot EMV dot underscore JWT EMV.
Perfect.
Now that we have this in place what's that JWT secret.
There we go.
Sorry for misspeaking right there.
Got a little ahead of myself.
So now we are referencing the S.E.C. RTT.
Just checking my spelling.
Geez I'm really going crazy and everything is looking good.
And now we can test the application out.
So we're gonna make sure that we save all of the files I'm also going to remove these challenged comments
as the last thing to do is to test our work.
And down below.
Yes.
It's still failing.
We restart the server.
It picks up on the new in variables we created.
And right here the server is now working which is a good first step.
But we're gonna do from here is create another user.
Then we're gonna go ahead and try to access their profile to test things out over inside of postmen.
We have our create user request.
Now this email is already registered.
I could go ahead and choose to delete them or I could just switch it up.
I'll go ahead and use Andrew 3 example dot com.
I'll save that request and I'll also switch out my log and request to use the same email.
So that works going forward though that steps not necessary.
Now we're actually going to create that user.
So let's go ahead and knock that out by firing off the create user request.
They're showing up down below which is a good first step.
Now let's go ahead and make sure we can fetch them using read a profile right here.
I'll read my profile and it's showing up as expected.
So this proves that everything is working.
I'm able to communicate with the database and my J.W. ts are getting created and verified correctly.
Now that we have this in place we're really only halfway done.
We have these environment variables defined locally.
But if we were to push the project to Heroku only this one would exist Heroku does not automatically
set these in the next lesson.
We're going to deploy this project to Heroku and we'll learn how to set environment variables for the
Heroku app as well.
Now we're also going to be able to do some other fun stuff.
We'll figure out how to ignore the config file to make sure that stays out of our get repo.
Let's go ahead and jump right in to the next one.