Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Add the program to compare the credentials a user supplies in the login form with user credentials in the Mongo database.
Security: Protecting against cross-site request forgery
Resources for adding password reset
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
At this point, we have a login form,
and we can preview it but
0:00
we need the programming logic to
authenticate users when they log in.
0:03
To do this, let's start by
rewriting the login post route.
0:07
I'll open the index.JS file
inside the routes directory.
0:11
Currently, we just send the test
message logged in, I'll delete that.
0:16
To start, let's check to make sure
the user has supplied their email
0:21
and password.
0:24
Obviously if they leave one of those off
the form, we can't authenticate them and
0:25
we should spit out an error.
0:29
I'll use a conditional statement to
check to make sure the email and
0:32
password are coming in
through the request.
0:36
If there is, will do something
to authenticate it, otherwise
0:40
we'll let the user know that they didn't
supply all the required information.
0:44
The 401 status code means unauthorized,
you can use it to indicate missing or
0:52
bad authentication, let's test it out.
0:56
I'll save this file and
switch to the terminal or console.
0:59
I'll need to make sure
mongod is running so
1:03
I'll type mongod, If you're on
Windows use the mongod executable.
1:05
Now open a new tab and
start the server by typing nodemon.
1:11
If I go to the login form,
make sure I leave the fields empty,
1:19
hit the login button,
you'll see the error message, awesome.
1:23
Now, we need to add the programming to
authenticate the request when both fields
1:29
are filled out,
let's add the method to the user schema.
1:33
We can call this method
to authenticate a user
1:36
because we are adding it to the schema,
1:41
we put the code in the user.js
file in the models folder.
1:45
We add this authenticate method
to the schemas statics object.
1:56
In mongoose the statics object lets
you add methods directly to the model,
2:00
we'll be able to call this
method when we require the model
2:04
in our other files like our route file.
2:08
The function that I'm defining
here takes three arguments,
2:11
the email and password submitted
with the form and a function.
2:15
We'll add that function in the route,
but in a nutshell
2:20
that function will either log the user in,
or give them an unauthorized user error.
2:23
Now in the authenticate function,
I'll tell
2:29
mongoose to set up a query to find the
document with the user's email address.
2:34
Then I'll use the exec method
to perform the search and
2:40
provide a callback to process the results.
2:44
If there's an error with the query,
we can simply return an error.
2:49
But, we also want to return an error if
the email address wasn't in any document,
2:54
in other words,
we couldn't find the user in the database.
2:59
We'll write a custom message in this case,
user not found and
3:04
set the status, the error status to 401.
3:07
So finally if we get through all of this,
3:13
there is a user in the database
with the supplied email.
3:15
So we can use bcrypt.compare method
3:18
to compare the supplied password
with the hashed version.
3:21
The compare method takes three
arguments a plaintext password,
3:31
that's what the user types into
the log-in form, the hashed password
3:36
from the retrieve database document,
and a callback function.
3:41
The compare method returns an error
if something goes wrong or result
3:46
which is a simple boolean value, true if
the passwords match, false if they don't.
3:50
If the password matches,
we return null and
3:59
the user document because we know that the
user logging in is who they claim to be.
4:02
What's the null value for?
4:08
Well, it represents an error value.
4:09
Node uses a standard pattern for
callbacks,
4:11
an error followed by other arguments.
4:15
In this case there's no error,
the authentication worked.
4:17
So we passed a null value,
followed by the user object.
4:20
With the authenticate
method added to our schema,
4:24
we can now call it from the login route.
4:27
I'll switch back to index.js I can
call this method on the user object.
4:29
Remember user is our model,
you can see we imported that up here,
4:38
at the top of the routes.
4:42
And authenticate is the method
that we just created,
4:44
I'll pass the email and password from
the form as well as a callback function
4:48
So within that callback function,
first let's deal with a bad login.
5:01
For example, the email doesn't match or
the password doesn't match.
5:06
I can do that by simply checking if
there's an error or if there's no user,
5:10
we'll create a new error signaling
that they submitted the wrong email or
5:14
the wrong password.
5:18
Like all authentication errors,
we give it a status code 401 and
5:20
then we simply return this, so
that the next error is processed.
5:25
So, after all [LAUGH] Of this,
at this point the user has filled out
5:28
the credentials correctly and they've
been authenticated against our database.
5:33
The last step is to create a session.
5:37
If the user is authenticated
then we can save the user's ID,
5:40
that's the ID drawn from the mongod
document for that user into a session.
5:44
Remember, session data is only stored
on the server, so this user ID
5:49
is never sent to the client browser, only
a cookie is sent containing the session ID.
5:54
This makes sure sensitive information like
the user ID is only kept on the server,
5:59
conveniently Express adds session
data to the request object.
6:04
So anywhere you can access the request
object, like in any route, you can set and
6:08
read session data.
6:13
Even better Express creates the cookie for
us automatically.
6:14
You also notice that we don't do
anything special to create a session.
6:18
Just by adding a property,
userID to the req.session and
6:22
assigning that property a value user._id,
6:28
we're telling Express,
either add the property of the session or
6:33
create a new session if one doesn't exist,
pretty nice.
6:36
Now, let me be clear what
this user._id is, is what
6:40
we'll get back from the authenticate
function when it's authenticated.
6:44
And user is our document,
it represents all the information for
6:48
a single logged in user, and
finally the underscore ID is that unique
6:52
ID that mongod gave the document when
it was inserted into the database.
6:57
Finally after all this they're
logged in and we'll redirect them to
7:02
the profile page, now we can also
add that to the register route.
7:06
That way once they are registered,
they're automatically logged in.
7:18
We haven't yet built the profile route,
so let's tackle that in the next video.
7:23
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up