‫Now it's finally time to use the login API
‫that we built in previous sections
‫and there is a ton of stuff to do here
‫in order to make the front-end interact with the back-end.
‫And so we're doing this in separate lectures.
‫Anyway, let's now get started.
‫And this is how it's gonna work.
‫So, we're gonna allow users to log into our website
‫by doing an HTTP request, or an ATEX call
‫as many people like to call it also.
‫And we're doing that HTTP request to the login API end point
‫that we implemented before using the data
‫that the user provides in this form that we have here.
‫So, remember that our API will then send back a cookie
‫which automatically gets stored in the browser.
‫And also automatically gets send back
‫with each subsequent request.
‫And as you will see, this is a fundamental key
‫in order to make our authentication system work.
‫But anyway, since we're doing
‫this HTTP request in the browser,
‫we will, of course, again, be working on the client side.
‫But anyway, since we're doing
‫an HTTP request in the browser,
‫we'll still be working on client side jobs script code.
‫So just like we did with the Mapbox implementation.
‫Alright?
‫So let's now go ahead and create a new file here.
‫And so that's in public, js, and new file,
‫which I'm gonna call login.js
‫and in the next video, we're actually going to bundle
‫all these separate JavaScript files
‫that we're creating here for the front-end
‫together into one big bundle.
‫Alright?
‫But for now, let's actually just focus on making
‫this login functionality work.
‫But anyway, let's now start by adding an event listener,
‫listening for the submit event on our login form, okay?
‫So, our login form has this form class here.
‫Okay, so let's now select this for element
‫and then on there, listen for the submit event.
‫I hope that you're familiar with this kind of logic
‫in the client-side JavaScript.
‫And so hopefully, this is nothing new for you.
‫So, document.querySelector,
‫which we use in order to select based on the class.
‫Add then that Selector name,
‫and now add EventListener, listening for the submit event.
‫So basically, an event that the browser will fire off
‫whenever a user clicks on the submit button on the form.
‫Add then in the collect function,
‫we're gonna have access to that event itself, okay?
‫And so the third thing that we actually do
‫is to say event.preventDefault.
‫Okay?
‫So this prevents the form from la-loading any other page.
‫Next up, let's actually get the email
‫and the password value that the user puts in.
‫And so these are, in this element, with the ID email,
‫and the ID password, okay?
‫So these two input fields
‫and let's get this data as well.
‫(typing on a keyboard)
‫So document,
‫get element by ID.
‫Email, and then we use the value property
‫in order to reach that value out there.
‫Not nodeValue, just value.
‫Let's duplicate this line, okay?
‫And so now let's do the actual logging in
‫in a separate function, okay?
‫Now we get here, this eslint error
‫and that's again because we have eslint
‫only configurated for not JS code.
‫And so let's actually disable that just like we did here.
‫So just grab this piece of code.
‫Alright?
‫And now as I was saying,
‫let's now create that login function.
‫So and just like this,
‫and this function is going to accept
‫an email and and a password.
‫And first of all,
‫let's just see if this code is actually working.
‫So we're going to alert,
‫so basically create an alert window.
‫And with this email and password.
‫Alright?
‫Now of course we also need to call this function
‫again with email and password.
‫And then finally, we also need to include this login file
‫into our base template, alright?
‫And again, as I was saying in the beginning,
‫in the next video, we're going to bundle
‫all of this front-end code here together
‫into one big JavaScript file.
‫Alright?
‫So that's a lot better for performance
‫and it's also a better developer experience for ourselves.
‫Anyway, this should now be working.
‫Let's just reload this page here.
‫So I have to fill in, validate here,
‫anyway, Chrome will not even allow me to submit the form.
‫Alright, so here we get our alert
‫with the email we just put in
‫and then the password, I guess,
‫doesn't show up because
‫we kind of specified two values there.
‫So instead, let's specify an object here
‫and see if it works then again.
‫(typing on a keyboard)
‫Well, I guess it tries to convert
‫that object to a string here.
‫Okay, but, it doesn't really matter here.
‫I'm usually more used to using Console.log instead of alert.
‫Alright?
‫But anyway, I'm sure it's working now here.
‫And so let's now go ahead and create this function.
‫So, in order to do these HTTP requests for the login,
‫we are going to use
‫a very popular library called Axios, okay?
‫And in the next video we're actually going to download
‫this library from NPM and bundle it together
‫with all our other scripts,
‫but for now, let's use it from a CDN.
‫So, let's just Google
‫Axios CDN, alright?
‫Then, go ahead and copy this one here,
‫and then, in our base script,
‫let's put it right here at the first one, alright?
‫So this will then expose
‫an Axios object to the global scope,
‫which we can then use in our login function, okay?
‫And so we can then now say Axios,
‫and then pass in the options for our request.
‫So first off, let's say that we're doing a post-request.
‫Then, we need a URL.
‫Alright?
‫So let's actually get that from Postman.
‫So, this is our URL here.
‫And we're also going to, of course,
‫append the host then on there.
‫So then here of course, it is http
‫and then local host basically.
‫And,
‫so this is our login input,
‫and now we need to specify the data
‫that we're sending along with the request in the body.
‫Alright?
‫And so that is email: email.
‫And so, as you already know, we can remove this email.
‫Okay?
‫So it's called email here, because our end point
‫expects the data to be called email, right?
‫So that's what we have here in the body.
‫We need to specify a property called email,
‫and one called password.
‫And so that's exactly what we're doing here
‫but it then has the same name as this parameter here.
‫And so it's enough to just say email
‫and the same applies for the password.
‫Okay?
‫Now, Axios here then returns a promise
‫and so let's actually use a single await
‫in order to wait for that value to come back.
‫So await here, and then async right here.
‫Now, keep in mind that this is client-facing code
‫and only the more modern browsers
‫can actually run a single await functions
‫but in this course, I'm not really going to go into that.
‫Okay?
‫Anyways, let's save the result of this awaiting the promise
‫into the result variable.
‫And then just, to take a look at the result,
‫let's say console.log result.
‫Okay?
‫Now one thing that I really like about Axios
‫is the fact that it's going to throw an error
‫whenever we get an error back from our API input.
‫So let's say that there is a wrong password
‫and so the server will send back a 403
‫and so basically, an error.
‫And so whenever there is an error,
‫Axios will trigger an error as well.
‫And so, that's very handy because, with that,
‫we can now use a try catch block.
‫Okay?
‫So basically in order to do some error handling
‫here on the client side.
‫So, for example,
‫when the user is correctly logged in,
‫then you want to display some message saying that,
‫and maybe some other logic,
‫but if not, well, then we're going to be entering
‫the catch block,
‫and can then, take some other action based on the error.
‫(typing on a keyboard)
‫So, let's take a look at the error as well.
‫And just to make sure, I also want to log the email
‫and password to the console.
‫So, let's try that here.
‫Reload our page,
‫(typing on a keyboard)
‫And I'm putting a wrong password in now, okay?
‫Test one, two, three, four, five.
‫Let's take a look at our console here as well.
‫And we get this error here from mapbox, js,
‫but don't worry about that.
‫We're going to fix that a bit later again.
‫Bur for now, let's take a look at what happens here.
‫And here we get some nice error, alright?
‫And so, actually when we need to take a look at here
‫is error.response.
‫And then point data.
‫Okay, and you will find this here in the Axios documentation
‫in case you're wondering where that is coming from.
‫Alright?
‫Let me actually just go ahead and copy this email because
‫it's not so good to always write it out manually.
‫And now we actually get some nicely formatted error here.
‫Okay?
‫And so this is basically exactly the jsencode
‫that we sent back from our server.
‫Right?
‫So, this is exactly the same
‫as we've been seeing in Postman.
‫So we get our entire error, the message, and also the stack.
‫And so we see that we probably didn't provide
‫the email and password correctly for some reason.
‫So let's go back, take a look.
‫Oh, so I did something weird here
‫where I passed an object with
‫both the email and the password.
‫And so I think that that's from before
‫when it tried to do that alert
‫and I guess I did this in the wrong place.
‫And so, that's why we actually saw undefined here.
‫And here we got this object.
‫So basically, email was this entire object,
‫and password was then this undefined.
‫Okay?
‫So now, this should fix it,
‫give it a reload.
‫Ah, now we get this correct error
‫that we were actually expecting.
‫So now it's an incorrect email or password
‫because I specified a wrong password, alright?
‫But now, let's actually remove the five
‫and so then test one, two, three, four, should be correct.
‫So, let's log in,
‫and now we get a 200 response.
‫So, a successful one.
‫So let's open this
‫and what we are actually interested in is the data.
‫So basically response.data
‫because this is then actually
‫where our jsen response is located.
‫So here, we get,
‫this data here, and we also get the status and the token.
‫And so, this is here our correct jsen web token
‫corresponding to this logged in user.
‫Now, what's really interesting
‫is to take a look at our cookies.
‫And we do that in Google Chrome at least
‫by clicking on this icon here
‫and then down here, you have the cookies.
‫And it also says that our connection is not secure
‫and that's simply because
‫we're not using HTTPS at this point,
‫but nevermind about that.
‫What matters here is that we now have this cookie
‫and indeed, it is called, jsen web token,
‫and it has exactly the jsen web token
‫that we see down here.
‫So, this is only the end, basically, of the string,
‫so you see that this is equal to what we have down here.
‫And it's this cookie here, will actually enable us
‫to build this entire authentication.
‫Again, because the browser will not send this cookie
‫along with every new request.
‫And let me actually show you in our back-end.
‫So let's go back there, and let's go to app.js.
‫And so now we're back in our note,
‫or actually in our Express code.
‫Now, in order to actually get access
‫to the cookies that are in our request.
‫In Express, we need to install a certain middleware.
‫And so we need to install that from an NPM package.
‫And so that's again, come to our other terminal
‫and then NPM install
‫the cookie parser.
‫Okay?
‫So basically, this package will then parse
‫all the cookies from the incoming request.
‫cookieParser.
‫Alright?
‫And now let's actually use it close to this body parser.
‫Okay?
‫So these two are very similar.
‫This first one parses the data from the body
‫and the second one parses the data from cookies.
‫And so now, if in this middleware here,
‫we can use request.cookies.
‫And so now for each request,
‫we will always display all the cookies in the console.
‫So, if we now re-load this page,
‫or really any other page,
‫and so let me just open this one here in a new tab.
‫So, if we now go back, we should see that cookie here.
‫And, indeed, here it is.
‫So this is the cookie that was just sent
‫into our application by loading that page in the browser.
‫And if I do that again,
‫then, you will see another one, right?
‫So here it is.
‫And so now we can use this in order to protect our route.
‫Alright, so let's try that out.
‫Okay?
‫But before we can do that,
‫we need in our off controller
‫to actually add that in here as well.
‫So right now, we're only reading the jsen web token
‫from the authorization header.
‫Right?
‫And only if they start with this bearer, kay?
‫So for the bearer token.
‫But now, we basically also want to read
‫the jsen web token from a cookie.
‫And so what we can do here is basically an else if,
‫so if there was no token in the authorization header,
‫well, then let's take a look at the cookies.
‫So request.cookies
‫.jsen web token.
‫So JWT, which is the name of the cookie,
‫and so therefore, in the cookies object,
‫there will be a property called JWT.
‫So this here, right?
‫And so if this exists, well,
‫then the token should be exactly that.
‫So request
‫.cookies
‫.jwt.
‫Okay.
‫And so now with this, we're also able to authenticate users
‫based on tokens sent via cookies
‫and not only the authorization header.
‫Great.
‫And just to test this out,
‫let's actually protect one of our routes here in the view.
‫And I will do that with this tour detail page, okay?
‫So that's just for testing
‫'cause of course it doesn't make much sense,
‫but I just wanted to show you that
‫as it is right now, our login is already working.
‫So let's import the authController here.
‫(typing on a keyboard)
‫And then, just like before, edit here into this route.
‫So authController.protect.
‫And so this is nothing new at this point.
‫And then only if the user is logged in,
‫we can go to the getTour.
‫Great.
‫So what I'm going to do now
‫is to basically delete this cookie first
‫just to show you what happens
‫when a non-logged in user tries to access that route now.
‫And so basically, if we remove this cookie,
‫it is like logging out the user, right?
‫So, if you now take a look our tours,
‫then that should look just fine.
‫But, if we now try to access this page,
‫we should get an error.
‫And indeed, there it is, saying that you are not logged in.
‫Fair enough.
‫So let's go back and let's actually log in.
‫Okay?
‫So here we go.
‫And then in the future,
‫we will of course also implement
‫like some alert windows here and all that good stuff.
‫But for now, again, let's just make it work.
‫And so you see that we're back
‫to having our nice cookie here, okay?
‫And so, let's now try to access this protected route.
‫And indeed, now it works.
‫Fantastic, that's really great already, right?
‫Now ideally, when a user is logged in,
‫we then want not to display these buttons here,
‫but instead, like some user menu or a picture of the user.
‫So basically showing,
‫that user is actually logged in, right?
‫So let's do that in the next video,
‫along with bundling all our JavaScript files together
‫in the front-end as I was explaining earlier.
‫So don't wait, let's move straight to the next one.
‫See you there.