Okay.
So we're ready to add our new authentication microservice.
We're just going to deal with all authentication and identity access management related functionality
in our app.
Let's go ahead and create this new app by going back to the CLI.
And we'll use the nest CLI and run Nest Generate app auth.
So this is going to go ahead with this normal process of creating a new application by creating a new
app's auth directory, updating our TS config and our package.json as well as the nest cli dot JSON.
We can of course go to the nest CLI and see the new auth application that was added.
So our first step in implementing authentication in our auth microservice is going to be to actually
implement the idea of users.
So we want this microservice to be able to create new users and authenticate or log in against those
users and obtain a JSON web token.
So the user will provide their credentials.
We'll give them back that token to authenticate them, which is a very common authentication mechanism.
And we can make use of this authentication mechanism in all of our different microservices that will
implement authentication.
So let's go ahead and get started.
Back in our terminal here we're going to generate a module called users.
And then it should ask us which project we want to use.
In this case we can say auth.
So we're also going to use the CLI to generate a controller here so that we can actually create new
users over HTTP.
And we'll select the auth project here you can see it create the new users controller and update the
users module.
So now if we go back to our auth module we can see we're importing the users module which is inside
this new users directory.
And the users module here has the user controller.
And this has the boilerplate users controller where we will specify a new post route here from Nestjs
common.
And this will be our async create user route.
So we're going to create the DTO for the create user route I'll create a new folder in the users directory
called DTO and we will create a create user dot DTO in this DTO directory.
So we're going to go ahead and export a class called Create User DTO here which will have two properties
an email of type string and a password of type string which we will need to create a new user.
So we're going to take advantage of class validator in this authentication microservice as well to validate
all incoming input from users.
So let's go ahead and use the is email decorator here from class validator which will check if this
string is a valid email.
And then for password we're going to use the is strong password decorator here to specify that we want
a strong password.
And it will also check to see if the value is a valid string.
So now back in the users controller let's go ahead and add the body annotation here from Nestjs common
where we'll specify the create user DTO of type create user DTO.
And in here we're going to return this dot user service which doesn't exist yet and call create and
pass in that create user DTO.
So of course there is no user service right now.
We can go ahead and generate it with the CLI swapping controller out here with service to generate a
user service underneath the auth project.
So now we have a user service.
We'll go into our constructor here and actually inject the newly created users service of type users
service.
So this method does not exist on the service yet.
You can see it's newly created in this users directory.
Let's go inside of here and add our async create method here which takes the create user DTO of type
create user DTO.
And inside of here, of course, we want to reach out to our repository and actually persist this user.
Now to do this we will manually create a users repository and we'll create a new file called users dot
repository dot TS.
And of course like our other repositories, this will be an injectable class so that we can inject it.
And we'll export a class here called Users Repository.
And as you might have guessed, this will extend our abstract repository.
And you can see here it's trying to import it directly here.
Let's change this out for add app slash common.
Now just as we did before in the reservation service we need to supply the abstract repository with
the schema.
So now in the users directory we can create a new models folder where we'll include our user dot schema
dot ts.
Now we can make this super easy by going into our existing reservation schema and copying everything
over and.
Hasting into the new user schema so everything will stay the same of course, except for the naming
conventions and properties.
The reservation document here will be changed to the user document, and the reservation schema will
be a user schema and this will use the user document.
Now we will specify the two properties that exist on the user the email of type string.
And we'll of course decorate this with the prop decorator.
And then we have the other property here the password of type string.
So now back in the users repository we can actually supply the newly created user document document
here from our models directory.
And just like we did in the previous repository, we're going to create that read only logger here,
which will be a new logger from Nestjs Common directly.
And we'll supply the user's repository dot name here for some context.
Now, just like we did in the other repository, we're going to have a constructor that will use the
inject model decorator from Nestjs mongoose.
And inside of the inject model, we're going to pass in the injection token that we're going to set
up later.
In this case it will be the user document dot name itself here.
So this will be the user model that will be of type model from mongoose.
And the type that we provide here will be the user document.
So all we have to do now is pass this up to our abstract repository by calling super and pass that user
model.
So now we can reap the benefits of this abstract repository by creating a constructor in the user service
that injects the user's repository of type user's repository.
And then in create, we will simply call this dot users repository dot create and pass in that DTO.
So now it's time to wire everything up.
We're going to go inside of the users module.
And since we're instantiating a new repository and making use of the database connection, we of course
need to import the database module as well as set up our user schema.
So let's make this easy by going to the reservations module and importing the database modules here.
And we'll copy them to the users module.
So we'll add an imports array here and paste in the database module imports.
We will import the database module up top from app slash common.
And we will change the reservation document out for the user document for the injection token.
And the schema itself will be a user schema from the models user schema.
Last but not least, don't forget to actually add the users repository that we've created to our providers
array.
So Nestjs is aware of it.
So now back in our terminal, we can just make sure that everything is wired up correctly by running
npm start dev and then passing in the auth project here to make sure we start the auth app.
And this will not use docker compose, this is just using our local machine.
So of course we're not going to be able to connect to the MongoDB container that's running because we
aren't currently running it in Docker.
That's going to be our next step to actually dockerize the authentication app.
So we can continue to compile it alongside our other microservices.
Let's go ahead and dockerize our app next so that we can test out our new user creation functionality.
Okay.
So we're ready to start dockerizing our authentication microservice.
And so the easiest way to do this is we're going to go into our auth directory.
And we're actually going to create a new Docker file in here just like we did reservations project.
And to speed things up we can go ahead and just copy over our existing Docker file for the reservations
project and paste that in here.
The only change we're going to have to make is the command to start the node process.
Instead of going into the reservations folder, we're now going to go inside of the auth folder and
start the Main.ts that way.
Then we can open up our Docker compose here, and let's add a new service to our services list the auth
service here, where we will have a build section.
Just like the reservations service, we have the context at the root where we're currently at.
We are going to copy over the docker file from dot slash apps, slash auth slash docker file.
And of course our target here will still be development.
Let's go ahead and copy over the rest of the configuration from the reservation service and paste it
in here.
And we're going to have to change the start command here to start the auth project.
And we're also going to change the port we're running on to be on 3001.
So we don't conflict with the reservation service which will be running on port 3000.
So let's make.
A similar change inside of the auth service will open the main.ts and change the port.
We're listening on to 3001 now.
Back in the terminal, we can go ahead and run docker compose up so we can test things out.
Back in postman.
I'm going to change the port here to 3001.
So we point at the authentication service.
We'll launch a Post request at slash users.
And we'll edit our body here to include an email.
And I'll just use a test email here test at example.com.
And we'll have that strong password as well.
So I'll add a random strong password 123.
And then we can send this post request off to the server and see we get that 201 created back.
Which means we have successfully created the user.
And we don't have a way to get the user currently, but we will soon be able to log in with this newly
created user.
However, if we go ahead and try removing the email here and sending this, we can still see that the
request succeeds.
And that's because we haven't set up class validator or Nest Pinot logger in our auth service.
So let's go ahead and do that now back in our main.ts in the auth service, we'll do the same thing
we did in the reservation service where we attach the validation pipe to a global pipe.
And we also used the nest peanut logger here to get the Nest peanut logger working properly.
So let's copy both of these and paste them into our Main.ts for the auth service here.
We'll of course update our imports here as well, and make sure we import the logger from Nestjs piano.
And then we're going to go into our auth dot module and make sure we import the logger module.
And make sure we import the logger module from app slash common here.
So now if we go back to the terminal we can see sleeper auth here is using the nest logger.
And we successfully started up.
And now if I go back to postman I send this request off.
Of course we get two validation errors saying that the email does not exist.
So I'll change my password here as well to use a capital letter and an exclamation mark.
And now we can see our payload succeeds.
So we're finally ready to actually start implementing our authentication with JWT.
Now that we have the ability to create new users and take advantage of the popular authorization library
passport that integrates very nicely with Nestjs to implement this JWT auth, let's go ahead and do
that next.