WEBVTT 00:01.530 --> 00:05.640 So now that we have the middleware in place on the front end to check authentication, it's time to 00:05.640 --> 00:11.310 modify what happens when a user logs in because we're checking for a value in the session, but we're 00:11.310 --> 00:12.440 never putting anything there. 00:12.480 --> 00:21.120 So let's go back to our I.T. and let's open up the login page, go HTML right there and we'll find the 00:21.120 --> 00:21.900 actual form. 00:22.050 --> 00:26.820 Now, that form has an idea of login form, but it has no action and we're going to give it an action 00:27.300 --> 00:31.440 will point to a route that doesn't exist yet and it's post login. 00:31.440 --> 00:33.760 So we already have a route for get log in the displays. 00:33.780 --> 00:39.240 This page now we need to build one that actually posts and of course that means we need to come down 00:39.240 --> 00:43.580 here on the VAL method and write down here. 00:43.590 --> 00:46.020 We're not going to code location H ref. 00:46.720 --> 00:47.520 We'll get rid of that. 00:48.570 --> 00:56.790 And instead we'll submit that formal document Dockett Element by ID and it's called Log in lowercase 00:56.790 --> 00:58.500 log in underscore form. 00:59.180 --> 00:59.990 We want to submit it. 01:02.370 --> 01:09.470 So we need to now go to our roots file for the front end and find that log in root right here. 01:09.480 --> 01:10.650 This is the GETRUDE. 01:10.800 --> 01:13.440 Let's just duplicate that and make it a post route 01:16.950 --> 01:19.200 and we'll point to a handler that doesn't exist yet. 01:19.800 --> 01:23.040 Login page will call it say log post, login page. 01:26.970 --> 01:29.760 OK, now let's go to our handlers. 01:29.790 --> 01:36.660 So that's in our handlers thought go file and we'll create a route to handle the post login func receiver 01:36.660 --> 01:38.400 of pointer to application. 01:39.630 --> 01:43.680 We'll call this post login page again, get a handler. 01:43.680 --> 01:49.470 So W response writer and our pointer to a request. 01:53.430 --> 01:57.870 Now what's going to happen in here is first of all, we're going to do something that you should do 01:57.870 --> 02:03.860 any time someone logs in or log out and that's regenerate or renew your token in the session. 02:03.870 --> 02:05.340 So that's really easy to do. 02:05.370 --> 02:12.330 We have access to the session in our app variable and we're just going to call renew tokens right there. 02:12.600 --> 02:15.150 And all it takes is one parameter and that's the context. 02:16.140 --> 02:17.460 And that's just good practice. 02:17.490 --> 02:18.960 You can do this without doing that. 02:18.960 --> 02:21.630 But this is a good idea from a security point of view. 02:22.740 --> 02:31.710 Now we need to pass the form so there is a sign the value of our passport and we check for an error. 02:32.640 --> 02:35.250 If error is not equal to nil, then you can do whatever you want. 02:35.250 --> 02:42.060 I'm just going to leave the error after error log dot print line and I'll print the error and just return. 02:43.950 --> 02:45.780 And of course you can do whatever you want in there. 02:47.250 --> 02:55.950 Now we'll get our two values, which are email, which comes from hard up form dot get and we call that 02:55.950 --> 03:03.260 email all lowercase and password is our form douget password. 03:04.110 --> 03:11.640 Now at this point what we want to do is query the database and do a comparison between the password 03:11.640 --> 03:16.620 that they've supplied, which is a test password and the hash that we have stored in the database. 03:17.100 --> 03:20.190 So in order to do that, we need to go over to our models. 03:20.190 --> 03:20.760 Don't go. 03:21.600 --> 03:29.220 So let's go there and go to the very bottom and I'll create a new function here and it's similar to 03:29.430 --> 03:29.530 me. 03:29.580 --> 03:36.810 Create the function description first and DB model and we'll call this just authenticate and it will 03:36.810 --> 03:42.780 take two parameters, which will be the email and the password, which we get from the form both in 03:42.780 --> 03:43.770 the form of strings. 03:44.130 --> 03:50.550 And we're going to return an end, potentially an error now as I usually do. 03:50.550 --> 03:53.970 Let's go copy our contact stuff from the function right above it. 03:54.870 --> 03:57.420 So I don't mistype that and paste it in. 03:59.220 --> 04:05.280 And let's create two variables ver ID, which is an end and that's where will store the user ID if we 04:05.280 --> 04:11.760 can get the user from the database and our hashed password, which is the hash hashed password that's 04:11.760 --> 04:14.690 stored in the database and we'll use that for a comparison. 04:15.810 --> 04:19.800 So now let's try to get a user so we'll create a row. 04:20.100 --> 04:28.610 That's our variable and that's assign the value of amd, db query row context and add the context and 04:28.620 --> 04:38.160 add a query which is nothing more sophisticated than select ID and password from users where email equals 04:38.160 --> 04:38.760 questionmark. 04:42.090 --> 04:46.440 And our substitution is email, we're looking up, a user are trying to. 04:47.160 --> 04:51.870 So let's see if there's an error error as a sign the value of Rodust scam. 04:52.020 --> 04:57.120 And we're going to scan into ID and hashed password. 04:59.440 --> 05:08.590 If there's an error, if error is not equal to nil, then we'll return it and the error, otherwise 05:08.590 --> 05:09.500 we found a user. 05:09.520 --> 05:11.260 Now we need to compare their password. 05:11.260 --> 05:17.200 And the way that this happens is very similar to the way we're looking for valid tokens on the back 05:17.200 --> 05:17.420 end. 05:17.520 --> 05:23.500 So we're going to look for an error error as a sign the value of from from the decrypt package right 05:23.500 --> 05:31.270 there, BCR, why we're going to call COMPAR hash and password and we're going to compare a slice of 05:31.270 --> 05:31.750 bytes. 05:33.190 --> 05:40.630 And the first value is the hashed password and the second value is byte. 05:42.450 --> 05:44.560 The password that the user typed in. 05:46.320 --> 05:51.600 So at this point, we check for an error if error in the first case, I'll look for if it's exactly 05:51.600 --> 06:01.830 equal to decrypt, dot or mismatched hash and password, then will return zero because we don't have 06:01.830 --> 06:04.200 a user and errors dot new. 06:04.950 --> 06:08.460 And I'm going to just say incorrect password. 06:10.010 --> 06:10.440 OK, 06:13.350 --> 06:17.550 now if it's not that kind of error else, but it is error. 06:18.000 --> 06:30.000 So else if error is not equal to nil, you have to do that and we want to return just zero and whatever 06:30.000 --> 06:34.320 the error was, otherwise we'll return the ID. 06:34.500 --> 06:36.840 We found a matching user, no error. 06:37.380 --> 06:39.810 The user exists and the password matches. 06:40.770 --> 06:42.380 So now let's go back to handlers. 06:44.750 --> 06:45.960 We'll just make this really simple. 06:46.860 --> 06:49.320 So look for any potentially error. 06:49.320 --> 07:01.030 And they come from after DB authenticate and we handed email and password if error is not equal to nil. 07:02.220 --> 07:07.200 Now, at this point, you could store an error message in the session, check for the existence of that 07:07.200 --> 07:09.960 on your login page and display the error message. 07:10.230 --> 07:14.160 But I'm just going to do a redirect right now, redirect. 07:14.160 --> 07:19.620 And we're going to redirect our back to the login page with no message whatsoever, which isn't very 07:19.620 --> 07:20.010 friendly. 07:20.550 --> 07:22.260 But it's easy enough for you to add that. 07:22.260 --> 07:23.790 And I'll just go status to see other. 07:29.210 --> 07:29.950 And we'll return, 07:32.780 --> 07:40.610 otherwise they actually logged in, so now we put that idea in session after session, not put, which 07:40.610 --> 07:46.190 is a method not pop put, which is one available to us right from the session's package. 07:46.190 --> 07:47.660 And it requires the context 07:50.210 --> 07:51.920 and it requires something to call that. 07:51.920 --> 07:56.150 And if you recall in the middle where I called it user I.D., exactly like that. 07:56.540 --> 08:01.670 And we'll put the idea in there and I will read to the homepage http redirect 08:04.640 --> 08:09.230 or go to the homepage http dot status, see other. 08:12.110 --> 08:14.590 So that should actually take care of it. 08:16.100 --> 08:18.530 So let's stop our application of it's running mate. 08:18.620 --> 08:21.260 Stop, start. 08:24.950 --> 08:31.010 Let's go back to our Web browser, reload this page, you can see that I'm not logged in because it 08:31.010 --> 08:31.990 says log in up here. 08:32.000 --> 08:37.880 So let me logging that example dot com and I'll put the wrong password in. 08:39.530 --> 08:41.330 And I should just bring me right back to this page. 08:43.030 --> 08:44.230 And it does good. 08:44.260 --> 08:48.780 OK, so we have invalid authentication credentials, and that's, of course, from the back end and 08:48.790 --> 08:50.710 not from the front end, but it doesn't matter. 08:51.130 --> 08:55.470 Now, we'll put a valid password in there, which happens to be password all lowercase. 08:55.480 --> 08:56.830 And if I typed out correctly. 08:58.270 --> 09:02.860 I get taken to the homepage now, I should be able to go to the virtual terminal page because I have 09:02.860 --> 09:06.700 that value in my session and I can't perfect. 09:07.330 --> 09:10.580 So the next step is to actually implement the logout logic. 09:10.600 --> 09:13.420 Now, you might think it works and it certainly looks like it does. 09:14.350 --> 09:19.510 But at this point, I still have that user ID in my session and I need to get it out of there when we 09:19.510 --> 09:20.020 log out. 09:20.500 --> 09:22.600 So we'll take care of that in the next lecture.