We've now added in two additional pieces of code to our user dot J as file so the priest spoke right
here is gonna make sure that we always salt and hash a password anytime that we attempt to create a
new user and store them inside of our database.
The second thing we put inside of here was a method attached to every user that it gets created.
That's going to automatically compare a password provided by the user against a password stored inside
of our database so we can easily call this function now.
Anytime a user tries to log in.
Speaking of which let's go back over to our auth roots file and add in some code to log our user in
OK.
So back inside of all throughout I'm going to add in a new post request handler underneath the existing
one.
So I'll say router dot post and anytime someone calls the sign in route we're going to run this function
as usual this callback will be invoked with a request and response object.
So inside of here whenever a user tries to sign in we're going to expect that they provide us with an
email and password.
Those email and password properties will be on the record body property.
So let's fold First pull those off like so and then we'll make sure that a user actually provided an
email and a password.
So we'll say that if there is no email or if there is no password then let's just give up we're going
to return early we're gonna send back a response that they status once again a 422 and we'll send back
an object with an error of must provide email and password
so now we get past that check that we can start to go through the log and process the first thing we
need to do is pick a user out of our database with the supplied email so we can do so by using the User
model we have up here coming from mongoose.
Remember this user model right here is how we interact with all the users that are stored inside of
Mongo so in particular we're going to do an a wait with user dot find one find one method is going to
taken an object in our case we want to look for some particular user with an email of email and of course
as usual we can condense that down to just email like so now I'm using the await syntax right here because
find one is going to take some time.
Remember this is a asynchronous operation because Mongoose has to reach out to our Mongo DB database
which just takes some amount of time.
So I'm gonna make sure that I mark this function right here as being async so we can actually use that
await syntax then we're going to assign whatever we get back to the user variable like so now we find
one fails to find anything then user is going to be NULL which indicates that sorry we did not find
a user with that given email so we'll do an immediate check right here and see if the user provided
or whoever made the request provided an email that's not in use by any user inside of our database.
So we'll see if there was not a user found then once again let's return early we'll set up a rez with
the status of four or four and we'll say error email not found sorry we didn't find anyone with that
given email so then after that we can attempt to go through that password comparison.
So this user model right here is going to have an email and a hash insulted password tag attached to
it.
So we want to compare that password against the password that the user provided to our sign in method.
So we're going to call a wait because remember we made this thing returning a promise user dot computer
password and we'll pass in the supplied password by the user remember if something goes wrong with that
comparison process or if the passwords don't match up then the promised return is going to be rejected.
So we have to wrap this thing in a try catch statement so I'll put in a catch that's gonna receive whatever
went wrong inside that era object and then inside of here if something went wrong.
Well once again let's return early so we can do a rest status and we can put a status on here for 22
or alternatively if you want to we could do a four or one of forbidden if we're trying to indicates
that there's something kind of wrong with this underline request so we could do either a fortune in
two or three for one of forbid entirely up to you and we'll send back once again an error of invalid
password or email.
Now I said just a little bit ago that whenever a handling authentication in general we want to give
kind of opaque error messages so we might decide to actually use the same error message right here as
the one whenever we do not find the user's email because technically right now if we send back the message
email not found that could allow some malicious user to Detective someone to give an email address has
ever signed up to our application.
So we might decide to just use the same password in both cases just to hide whether or not someone with
given e-mail has actually signed up.
Now if we do that we would probably want to make sure that these status codes line up as well because
otherwise there would once again be some kind of differentiating factor there.
So I would just change them to be identical either for 22 for both or for a four for both or whatever
else OK.
So if we've now successfully compared our password then we want to make sure that we generate a Jason
token once again and send it back so that the user can then authenticate themselves on future requests.
So inside of here we will once again generate our token by calling JWT dot sign.
We want to sign a payload with the user I.D. coming from the user model right here.
And just like before we want to hash their I.D. So underscore I.D. And then remember the second argument
is going to be our assigning key it must be consistent throughout all uses of JWT throughout our application.
So I can make sure that I use the exact same key as before backup here inside of our previous request
handler.
So in my case it is my secret key so I'll go back down and provide that as the second argument to sign.
Then finally we can send back the token that we generated.
I'm just going to stay consistent with how we sent it back before.
So I want to send back an object with a key of token and the value being the token so after we generate
our token I'll do a resort send with token like so.
And that should be it.
So I think that we're now ready for a quick test.
This video is actually going a little bit long but yeah let's just take a quick pause and I'll do a
quick test of everything we just wrote in the next video.
Make sure that we can sign up and then sign in with the given password.
So quick pause and I'll see you in just a minute.