WEBVTT 0 00:00.840 --> 00:08.880 Now while we've been developing this module with every level of increased security I've been committing 1 00:08.940 --> 00:16.140 the code for each of these stages just so that later on you'll be able to check out the commits that 2 00:16.140 --> 00:22.050 you want to review and check against your code easily. So you can see that we've got level 1 where 3 00:22.050 --> 00:24.240 we've got username and password only, 4 00:24.240 --> 00:25.370 and then level 2 where 5 00:25.420 --> 00:31.620 we added encryption to our password field. But there would be a bit of a security flaw that's introduced 6 00:31.890 --> 00:39.360 by committing all of this code to a remote Git repository like GitHub. Because if I go ahead and pull 7 00:39.360 --> 00:47.850 up the GitHub page for this particular project you can see everything that I've committed including 8 00:47.940 --> 00:55.980 all the code that's inside my app.js which as you remember contains some secrets in there namely 9 00:56.010 --> 00:59.910 the key that we used to encrypt our database. 10 01:00.240 --> 01:06.970 So this is now on the internet being crawled by Google completely searchable. 11 01:06.990 --> 01:15.600 Anybody can see my encryption key which also means that anybody can decrypt my encrypted database using 12 01:16.050 --> 01:17.370 this secure key. 13 01:17.380 --> 01:18.600 So it's not very secure 14 01:18.600 --> 01:26.490 essentially. It's very easy for people to crawl GitHub looking out for these secrets and API keys that 15 01:26.490 --> 01:28.070 they can take advantage of. 16 01:28.200 --> 01:34.120 And very often in the development world you hear stories like this where a developer put AWS 17 01:34.130 --> 01:43.050 keys on GitHub then bad things happen. And it's because currently we're in a bitcoin mining frenzy era. 18 01:43.050 --> 01:50.730 And to mine Bitcoin you need a lot of computing resources and those resources get directly turned into 19 01:50.730 --> 01:57.870 money providing a huge incentive for people to scrape the internet for developers who've accidentally 20 01:57.870 --> 02:00.450 published their secret keys. 21 02:00.450 --> 02:08.100 And this is a good story as well that I'll link to in the course resources where this guy Luke had accidentally 22 02:08.100 --> 02:10.930 published his API keys onto GitHub. 23 02:11.130 --> 02:19.620 And then he racked up an AWS bill of over 3000 dollars in a very very short space of time. 24 02:19.620 --> 02:26.220 Now I think the ending to the story was a happy one and Amazon AWS actually refunded him the money 25 02:26.730 --> 02:30.830 but I'm not sure everybody is as lucky as he was. 26 02:30.960 --> 02:39.060 So these are some really cautionary tales about keeping your secrets, your API keys, off the Internet 27 02:39.120 --> 02:43.530 where it's publicly searchable and where people can steal. 28 02:43.740 --> 02:48.710 So that's all very well and good but how exactly do we do that? 29 02:48.720 --> 02:57.120 Because obviously for our app to work we need these secrets to be able to encrypt our database. And for 30 02:57.120 --> 03:03.390 us to be able to collaborate with other people or simply just using version control or backing up our 31 03:03.390 --> 03:07.020 project to GitHub then we will need to publish it 32 03:07.020 --> 03:07.320 right? 33 03:07.680 --> 03:14.760 So the way that developers solve this conundrum is through using something called environment variables. 34 03:15.450 --> 03:22.770 And environment variables are basically a very very simple file that we're going to keep certain sensitive 35 03:22.770 --> 03:27.220 variables such as encryption keys and API keys. 36 03:27.270 --> 03:35.130 So in this lesson I want to show you how we can do this using a really popular package called dotenv. 37 03:35.640 --> 03:41.730 And you can see just through the sheer number of weekly downloads that it is a really heavily dependent 38 03:41.730 --> 03:49.580 upon module to keep everybody's secrets off of the Internet safe and secure. 39 03:49.770 --> 03:54.990 So let's get started by installing this thing called dotenv. 40 03:55.020 --> 04:00.230 So I'm still in my secrets repository and I'm going to install this thing called dotenv. 41 04:00.260 --> 04:05.610 So now that it's installed the next thing to see is how do we use it. 42 04:05.610 --> 04:14.190 Well the documentation tells us that as early as possible in your application require and configure 43 04:14.220 --> 04:15.180 this package. 44 04:15.210 --> 04:21.830 So I'm just gonna straight up copy this line of code and paste it right at the very top of my app.js 45 04:21.830 --> 04:29.160 over here. And you can see in this case we're not actually setting a constant for it because all 46 04:29.160 --> 04:35.790 we need to do is just require it and then call config on it and we don't need it ever again. 47 04:35.790 --> 04:42.780 It will be active and running and all we need to do now is to define our environment variable. 48 04:42.780 --> 04:48.270 Now it's important that you put it right at the top because otherwise if you try to use an environment 49 04:48.270 --> 04:52.170 variable and it's not configured then you won't be able to access it. 50 04:53.100 --> 04:56.160 So what exactly are environment variables? 51 04:56.250 --> 04:57.620 Well let's go ahead and create them 52 04:57.630 --> 05:04.600 now. We have to first create a dotenv file in the root directory of your project, 53 05:04.620 --> 05:08.710 so that means in this particular folder here. 54 05:08.820 --> 05:13.400 So let's go ahead and create a new file by hitting the a key. 55 05:13.860 --> 05:19.980 Alternatively you can go into hyper and make sure you're in the root directory and simply write touch 56 05:20.280 --> 05:20.910 . 57 05:20.910 --> 05:27.900 env. Now it's really really important that when you name this file .env can't be used like a file 58 05:27.900 --> 05:28.520 extension. 59 05:28.530 --> 05:32.250 It's not like .mp3 or .png. 60 05:32.250 --> 05:39.870 This has to be the entire name of the file. And just like other files like .git, this is a hidden file. 61 05:39.870 --> 05:46.020 So that means when I hit enter and create that file and I do an ls on my current directory I won't 62 05:46.020 --> 05:53.010 see it. And it's only when I do ls -a revealing all of my hidden files do I see it created here. 63 05:53.580 --> 05:58.730 But because we have Atom we can also see it inside Atom here. 64 05:59.310 --> 06:07.470 So now that I've created my file the next step is to add my environment variables to that file. And the 65 06:07.480 --> 06:16.410 format you have to follow is NAME=VALUE and there shouldn't be any spaces in between and nor 66 06:16.410 --> 06:18.880 should there be any quotation marks 67 06:19.050 --> 06:22.050 and the name should ideally be snake case, 68 06:22.050 --> 06:27.280 so words separated by underscores and they should all be capitalized. 69 06:27.300 --> 06:28.790 This is just convention. 70 06:28.830 --> 06:31.830 But I strongly recommend you to follow it. 71 06:31.860 --> 06:37.760 So let's go ahead and define the environment variables that we want to save. 72 06:37.770 --> 06:43.350 So the top contender is of course this constant code secret. 73 06:43.350 --> 06:53.370 So let's go ahead and cut it out of our app.js and paste it into our .env file. And let's reformat 74 06:53.370 --> 06:59.030 this so that it complies with the formatting that they want us to have. 75 06:59.040 --> 07:01.000 So let's first delete the const, 76 07:01.050 --> 07:06.870 this is not a Javascript file. We don't need any const or semicolons, 77 07:06.870 --> 07:13.550 so those are gone. Then we're going to rename the environment variable to make it capitalized. 78 07:13.560 --> 07:19.170 So this is going to be secret. And then we're going to get rid of that space between the equal signs 79 07:19.740 --> 07:24.660 and we're also going to delete our quotation marks. 80 07:24.750 --> 07:32.520 Now in my case the full stop is a part of my encryption key and it's not just therefore grammatical 81 07:32.520 --> 07:38.720 sense because all of my passwords were encrypted with this key including the full stop. 82 07:38.730 --> 07:40.440 So I have to keep that in there. 83 07:41.190 --> 07:48.930 However if we say had, I don't know, an API key then we might write it something like this and it would 84 07:49.020 --> 07:54.370 also not have any sort of semicolons or other symbols at the end. 85 07:54.390 --> 07:57.390 You don't need it basically is what I'm trying to say. 86 07:57.480 --> 08:05.490 You also don't need to separate the lines with a comma as you will commonly see when we're writing code 87 08:05.490 --> 08:13.020 files because this is just a piece of plain text file that's going to be used to be able to render these 88 08:13.200 --> 08:16.340 little tiny pieces of secret information. 89 08:16.380 --> 08:22.020 So let's hit Save and I'll leave the API key in there as well just so I can show you how we can fetch 90 08:22.020 --> 08:22.730 it out. 91 08:22.890 --> 08:30.480 So let's say that we're running our app.js and we've already required our dotenv package and we've 92 08:30.480 --> 08:36.360 configured it to be able to access our environment variables then anywhere after this line we should 93 08:36.360 --> 08:40.370 be able to tap in to those variables by referring to them. 94 08:40.380 --> 08:44.720 So let's go ahead and log say are API key 95 08:44.760 --> 08:45.050 right? 96 08:45.570 --> 08:51.900 And to do that what we need to write is process.env. 97 08:51.900 --> 08:58.530 then comes the name of that key which is going to be API_KEY. 98 08:58.560 --> 09:09.540 So now if I hit save and I run my app.js then you can see printed over here is the content of my API 99 09:09.570 --> 09:11.740 key right here. 100 09:11.760 --> 09:17.250 So now that we've seen how we can get access to our environment variables let's go ahead and fix our 101 09:17.250 --> 09:21.060 code because as you can see at the moment it's breaking. 102 09:21.060 --> 09:26.570 And it's because we no longer have that secret specified inside our app. 103 09:26.660 --> 09:27.890 js. 104 09:28.050 --> 09:34.170 So right here we deleted our secret and we moved it into our environment file. 105 09:34.500 --> 09:43.740 So try and pause the video the change line of code over here so that our app continues to work as it 106 09:43.740 --> 09:44.300 used to. 107 09:44.610 --> 09:48.690 But now it grabs the secret from our environment variable. 108 09:52.760 --> 09:53.090 All right. 109 09:53.120 --> 09:58.670 So all we have to do is exactly the same as what we did up here. Instead of trying to tap into a variable 110 09:58.670 --> 10:03.110 called secret inside our app.js which now no longer exist, 111 10:03.110 --> 10:12.080 we're going to replace it with process.env. the name of our secret which is just the word SECRET 112 10:12.170 --> 10:14.590 in all caps. 113 10:14.720 --> 10:21.760 And now if we hit save and nodemon should rerun our server you can see we no longer have any errors 114 10:21.920 --> 10:25.040 and our server has started on port 3000. 115 10:25.220 --> 10:32.090 So we can just go ahead and just confirm that everything still works the same by trying to log into 116 10:32.180 --> 10:34.970 our user with the password qwerty. 117 10:35.120 --> 10:37.700 So everything is working just fine. 118 10:37.700 --> 10:43.010 Now some of you guys might have spotted the next problem that's coming along. 119 10:43.070 --> 10:53.000 If I go ahead and simply just commit my project with all of the changes as it is to GitHub I will also 120 10:53.000 --> 11:00.590 commit my environment file which defeats the whole purpose of creating environment variables, configuring 121 11:00.590 --> 11:04.820 it and changing our code to keep all of those secrets secret 122 11:04.820 --> 11:05.690 right? 123 11:05.720 --> 11:07.700 So what can we do? 124 11:08.060 --> 11:16.850 Well, if you remember previously in the Git and GitHub module we covered something called gitignore. 125 11:16.880 --> 11:20.310 So that's another hidden file that we add to our project 126 11:20.420 --> 11:29.120 that tells Git which files and which folders it should ignore when it's uploading the files to a remote 127 11:29.210 --> 11:30.310 like GitHub. 128 11:30.380 --> 11:38.000 And if you search for "github gitignore" then you'll see that they've created this very helpful collection 129 11:38.420 --> 11:43.280 of template files for different types of projects. 130 11:43.310 --> 11:50.570 So if we go ahead and search for our node gitignore then you can see that this is a template file that 131 11:50.570 --> 11:57.530 you can create as your gitignore and it will set up Git to ignore most of the files that you don't 132 11:57.590 --> 11:59.240 want to commit. 133 11:59.240 --> 12:01.710 So let's take a look at what that includes. 134 12:01.730 --> 12:07.490 So one of the most common things that we don't commit when we're creating Node projects are the Node 135 12:07.580 --> 12:16.580 modules because you can see it's a massive list of Node modules and it's a whole bunch of code and a 136 12:16.580 --> 12:18.080 whole bunch of dependencies. 137 12:18.080 --> 12:23.940 So it massively blows up our project when we're moving it online and offline. 138 12:24.080 --> 12:31.070 And as long as we've got access to the package.json then anybody who Git clones our project or 139 12:31.070 --> 12:37.790 downloads it will be able to simply run npm install and it will automatically pull down all of those 140 12:37.790 --> 12:40.460 dependencies inside the Node modules. 141 12:40.490 --> 12:46.790 So it's common practice to ignore the node_module folder in our Node projects. 142 12:46.790 --> 12:56.750 The other thing that is inside this template of gitignore is of course the .env file and this is 143 12:56.810 --> 13:04.670 the dotenv environment variable files. So you can see this is very very common and it's very very essential 144 13:04.970 --> 13:13.580 that you add this to your .gitignore file so that our secrets do not get revealed to the public 145 13:13.700 --> 13:14.810 on the Internet. 146 13:14.840 --> 13:17.210 So let's give that a go. 147 13:17.210 --> 13:26.310 Let's go into hyper, let's stop our server and making sure that we're still inside our project root folder 148 13:26.360 --> 13:37.040 we're going to create our gitignore file and that's simply .gitignore. We hit enter and now we should 149 13:37.040 --> 13:40.020 have a gitignore file. Here 150 13:40.070 --> 13:47.030 I'm simply going to copy and paste the template that comes from GitHub and I'm going to paste it 151 13:47.180 --> 13:50.770 inside here and then hit save. 152 13:50.780 --> 13:59.690 So now inside our project folder you can see we've got our .gitignore, our .env file and Atom 153 13:59.780 --> 14:06.260 is actually helpful enough to show you the files that will be ignored by showing it to you in this kind 154 14:06.260 --> 14:07.910 of greyed out mode. 155 14:07.910 --> 14:14.840 You can see this folder is not going to be committed neither this one or our .env file and everything 156 14:14.840 --> 14:21.230 else shows up in a slightly different color. But let's just confirm it for ourselves. 157 14:21.230 --> 14:29.630 I'm gonna go ahead and git add all of my files in my folder. And then I'm going to add a commit message 158 14:29.810 --> 14:42.830 which will simply be "Add Environment Vars". And now I'm going to git push to my origin master which will 159 14:42.830 --> 14:49.280 now push all of the things I've committed locally to GitHub. 160 14:49.280 --> 14:57.210 Now if any of this is confusing at all, be sure that you've definitely completed the GitHub and Git module 161 14:57.510 --> 14:59.310 and that you're comfortable with it 162 14:59.310 --> 15:03.760 because I go into a lot more detail on this in that module. 163 15:03.750 --> 15:05.030 So let's hit enter. 164 15:05.280 --> 15:14.490 And now if we go into our project folder and we refresh our project then you can see our .env file 165 15:14.640 --> 15:18.510 is not visible in our list of files 166 15:18.510 --> 15:27.210 and when we go into our app.js it simply refers to our process.env.SECRET and there's no 167 15:27.210 --> 15:35.460 way for anybody online to be able to see what our API key is or what our secret is unless they had access 168 15:35.700 --> 15:39.360 which keeps us and our encryption safe. 169 15:39.360 --> 15:49.920 However, remember that Git and GitHub works on a version control basis. So if you click on history for 170 15:49.920 --> 15:57.690 our app.js then you'll be able to see the entire commit history and all of the versions previous 171 15:57.690 --> 15:59.280 to the current version. 172 15:59.280 --> 16:05.700 And if we click on the level 2 encryption one you can see that one of the differences here is that 173 16:05.790 --> 16:14.580 we used to have our secret inside our app.js in plain text not inside our environment variables. 174 16:14.580 --> 16:21.960 So this is why it's really important that the first thing you do when you start any new project is to 175 16:21.960 --> 16:32.070 incorporate .env, create your .env file and as you create anything that should be secure to create 176 16:32.070 --> 16:33.880 it inside that file 177 16:34.020 --> 16:39.880 and to add that gitignore template before you push to GitHub. 178 16:39.890 --> 16:49.050 Now when we're ready to deploy our app to Heroku, they actually have a specific way of handling these 179 16:49.050 --> 16:56.490 config VARs because obviously for your app to be able to run it needs access to those secrets. And there's 180 16:56.550 --> 17:04.020 a special pane that you'll be able to see on your dashboard where you can set those config VARs especially 181 17:04.080 --> 17:13.470 inside Heroku and they'll keep those safe and off the Internet, so keeping your API keys and your encryption 182 17:13.470 --> 17:14.670 keys secure. 183 17:15.360 --> 17:22.080 So it follows exactly the same format as what we've seen in the .env and you access it in the same 184 17:22.080 --> 17:24.720 way by using process.env. 185 17:25.110 --> 17:31.380 Now in the next lesson we're going to get back to authentication and we're going to level up the security 186 17:31.380 --> 17:36.510 for our users by switching from encryption to hashing. 187 17:36.570 --> 17:39.930 So for all of that and more, I'll see you on the next lesson.