Add the program to compare the credentials a user supplies in the login form with user credentials in the Mongo database.
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 up