Okay.
So in order to start implementing our JWT authentication with Passport, we'll go ahead and stop our
app from running and we'll need to install some new dependencies here.
I'll go ahead and install nestjs slash passport as well as passport itself.
And then finally passport local here, which will be our first authentication strategy.
We'll also go ahead install the types for passport local here as a development dependency.
So we're also going to want to install the dependencies to be able to implement our JWT authentication.
So let's go ahead and NPM install Nestjs, slash JWT as well as Passport, JWT and Nestjs.
JWT is a package that helps with the JWT manipulation and then we'll go ahead and install the development
dependencies for types slash passport, JWT.
And once we have this installed, we'll go ahead and start our app back up by running Docker compose
up.
So now we're actually ready to start writing the code for the auth service here.
So let's go ahead and open up the auth module.
We're going to have to import the JWT module now and we import the module up top from Nestjs slash JWT.
So we need to configure the module with some environment variables and we can accomplish this by calling
register async on this.
And inside of here we can use a use factory and get access to the config service.
And so we're going to return an object here that has some environment variables.
The important thing being the JWT secret value, which is the special token that the JWT module uses
to actually verify incoming JWT against to make sure that they're valid.
So when we sign a new key, we use the secret.
And when we verify, we use the same secret.
So it's important that we keep this hidden away in an environment variable.
So we'll call a config service service here, dot get type string and we'll pull the secret, which
we don't have yet, but we will add soon.
And then we're also going to add sign options here where we can specify an expiration date on the token.
So I'll go ahead and create a string template literal here where we call the config service dot, get
JWT expiration.
And I'm also going to put an S at the end here so that we turn this value into seconds.
So now we have the JWT module all configured, but of course we don't actually have these environment
variables set up yet.
So let's go into our dot env at our root here and I've just used a random string generator to get a
JWT secret value here that I'll go ahead and paste in here.
And then for the JWT expiration, I'll give it a value of 3600 for 3600 seconds.
So now we have these environment variables for the auth service.
This is everything we need, which is great.
However, it's not really great here how we're actually mixing all of our different environment variables
for each one of our microservices when we don't actually need these environment variables for any of
the other microservices.
So let's go ahead and start addressing this by creating a unique dot m file for just our auth service.
And I'll go ahead and copy and paste all of these m variables into this new dot m for just the auth
and then I'll move the root dot env the original one, I'll move that into the reservation service and
get rid of the JWT information here now as well.
And so now what we'll have to do is open up our docker compose and actually tell Docker, compose where
to look for these M files.
So for our reservation service, I'll have a new M file key here where I'll specify where this dot m
is located.
In this case it's apps slash reservations slash dot env and then we'll do the same thing for auth here.
We'll have an m file and we'll point it to dot slash app slash auth slash dot env.
So now each one of these services is going to have their own individual dot env, which makes more sense.
And next, if we go back into the auth dot module, you can of course see that we are introducing new
environment variables here.
So what we'd like to do is in our config module we of course want to validate these environment variables
to make sure that they actually exist.
However, it's not great that we'll have to validate all environment variables for all of our services
in this one place.
So to get around this, I'm actually going to refactor our current approach towards configuration.
I'll go ahead and get rid of the config directory altogether in lib slash common.
So we only have the database and the logger, which of course is going to make our code a bit angry
because now the database module can't find the config module and that's okay actually.
So to fix this here, let's get rid of the config module import here and we'll get rid of it from the
database module itself.
The database module will just rely on the service that's calling the database module to have already
set up the config module here.
So let's go ahead and do that.
Exactly.
Let's go into reservations module and let's set up the config module directly in here.
So this way in each individual microservice, we can set up the config module specifically just for
this service, which I think is a better approach than how we were previously doing it.
So let's go ahead and import the config module from nestjs config and we'll call for route as we've
done.
And this time I'm going to set it to global so that the config module will be available to anyone that
needs it in this service.
And then we can add the validation schema back here.
So in this case, remember it was that joy dot object key here and we'll of course import Joy again
as import star as joy from Joy.
So we'll open up this object here and we'll add the MongoDB Uri back as a joy dot string dot required.
So now we have this config set up for reservations and you can see reservations starts up fine again
and then we'll do the same thing in the auth dot module.
I'll actually copy reservations module setup we have here, so I'll copy this config module.
We'll go back to the auth module and let's add the config module here.
We'll have to add the imports as well.
I'll import Star as joy from Joy here.
I think this an uppercase J and now we have that MongoDB URI, which is great.
But now we also want the JWT we also know will be a required string.
So we'll add that required here as well as the JWT expiration.
So these environment variables will only be checked in the auth service, which makes a lot more sense.
And now let's go back to our terminal here and actually restart our containers so that we load in the
dot m files that we updated in the Docker compose and you can see the reservations module starts up
successfully.
The auth module is having some issues here.
So let's go ahead and take another look.
The issue is here is we're not actually injecting the config service, so make sure we add the inject
property here and we'll inject the config service to the JWT module so it actually can inject these
values.
Now we can see auth starts up successfully as well.
So one more thing I want to do now that we have actually made the config module scoped to each individual
service as well as the M is in our main.ts right now.
We're hardcoding the port that we're listening on, which will not be great when we actually want to
deploy our apps.
So let's go ahead and fix this.
And in order to fix this, let's pull the config service out here by calling app dot, get config service
and we're pulling the nestjs config service here directly by calling app dot get, which allows us to
retrieve any injectable.
And now instead of listening on this hardcoded port, I want to actually call config service dot get
and then get the port here so that we're actually going to get the port value and I'll do the same thing
in our reservation service.
So let's copy this, go to our reservations Main.ts and we'll paste the same thing in here as of course
we'll need to import the config service as well.
Now we'll actually need to add the port to our M's.
So I'll add a port here for the reservation service to listen on to port 3000 and then I'll do the same
thing for the auth service.
But this time we want to listen on Port 3001 and then finally we'll add a new validation check here.
Make sure we have a port this time.
We know it's going to be a number that's required and same thing for the auth.
We will check that the port is also included and that it is a number here.
Now, you might also need to restart your containers as well to make sure we get that updated dot m
file and we can see everything starts up successfully here.