‫Welcome back.
‫So in this video, you're gonna learn a super secure way
‫of logging out users.
‫So up until this point, when we wanted to delete a user,
‫we would simply delete the cookie from our browser.
‫Right?
‫So something like this,
‫and then remove it.
‫However, the thing is that we created this cookie
‫as an http only cookie.
‫Remember that,
‫and so that means that we cannot manipulate this cookie
‫in any way in our browser.
‫So we cannot change it,
‫and we can also not delete it.
‫So let's just quickly take a look at that place in the code
‫where we did that.
‫So in the auth controller
‫up there where we actually create that cookie
‫so that is right here.
‫And so again, remember, that this means that we can not
‫manipulate the cookie in the browser in any way.
‫Not even destroy it.
‫So delete it.
‫So if we want to keep using this super secure way here
‫of storing cookies,
‫then how are we going to be able to actually log out users
‫on our website?
‫Because usually with JWT authentication
‫we just delete the cookie
‫or the token from local storage.
‫But well, again, that's not possible when using it this way.
‫And so what we're gonna do instead is to create a
‫very simple log out route that will simply send back a new
‫cookie with the exact same name
‫but without the token.
‫And so that will then override the current cookie that we
‫have in the browser with one that has the same name
‫but no token.
‫And so when that cookie is then sent along with
‫the next request, then we will not be able to identify
‫the user as being logged in.
‫And so this will effectively then log out the user.
‫And also were gonna give this cookie
‫a very short expiration time.
‫And so this will effectively be a little bit like
‫deleting the cookie
‫but with a very clever workaround like this, okay?
‫So let's do that here, right after log in.
‫So again when we're doing token based authentication
‫we usually never need an end point like this
‫but when we want to send a super secure cookie like we do
‫well, then we have to do it like this.
‫So, again, on the response we set the cookie,
‫and the secret is to give it the exact same name.
‫So just as I mentioned before,
‫and that is jwt.
‫So just like here, okay?
‫But here, we then send the token,
‫but now we will send simply some dummy text.
‫So let's say logged out,
‫and then the cookie options.
‫So an expire date,
‫like in 10 seconds from now.
‫So let's create a new date
‫based on
‫date.now
‫plus 10 seconds.
‫So that's 10 times 1000.
‫And also I'm going to set it, again, to http only.
‫Set to true,
‫but we do not need to set it as secure,
‫because in this case there is no sensitive data
‫that anyone can get a hold of.
‫Here we're missing the comma,
‫and so now all we need to do is send this response back.
‫So status 200
‫and let's simply mark it as success here.
‫Then in our route we need to add it, of course, as well
‫so that's at the user route
‫so let's do it right here after log in,
‫but this one will actually be a get request
‫because we're not going to send any data
‫along with the request
‫we're not changing anything,
‫we actually simply get a cookie.
‫And so that name actually makes sense.
‫Or that verb actually makes sense.
‫So log out,
‫and so now we are good to actually hit that route
‫just like we did here with our Axios library.
‫So export,
‫log out,
‫or actually const first
‫and so just like before
‫we're using a try catch block
‫which in this case is not really that important
‫because there can not really be an error while logging out,
‫right?
‫But anyway, just in case, for example,
‫we have no internet connection.
‫So in that case, we then will get a nice error
‫and let's actually do that first here.
‫So show error
‫logging out
‫try again.
‫Okay, but this here, as I said,
‫should not happen that often.
‫So instead
‫let's
‫do our request with Axios.
‫All right.
‫And so the method this time is get
‫and the URL is
‫similar to what we have here,
‫But it is
‫log out.
‫And then as the next step, let's also reload the page.
‫So that's what we always do manually
‫when we delete a cookie, right?
‫And so here of course we need to do it programatically.
‫Right?
‫And we need to do it here
‫because since this is an Ajax request we can not do it
‫on the back end side.
‫So we can't do it with express.
‫And so we need to, of course, do it manually here.
‫Right?
‫Otherwise we would technically be logged out
‫but our user menu would still reflect
‫so it would still show that we are logged in.
‫And so of course, we simply need to reload the page
‫which would then send the invalid cookie basically
‫to the server,
‫so that one that we just received without a token
‫and then we are no longer logged in,
‫and therefore then our user menu will disappear, okay?
‫So let's do that if there was a success.
‫So just like before, rest.data.status.
‫And so in this end point, we also send back
‫the status set to success,
‫and so we can once more test for that here.
‫And so if this is the case
‫well we actually don't even need this
‫so in this case widow location.reload.
‫And then something really important is that we actually
‫need to set it to true here,
‫and that will then force a reload from the server
‫and not from browser cache, all right?
‫Now and of course we need to mark it here as async,
‫and okay.
‫So this part here is really important again
‫because otherwise it might simply load the same page
‫from the cache
‫which would then still have our user menu up there.
‫But of course that's not what we want,
‫we really want a fresh page coming down from the server.
‫All right?
‫So we have our log out function
‫and now in the index we basically need to now trigger it
‫once we hit that button.
‫So let's create an element here first.
‫So the log out button
‫document.querySelector
‫and remember how we created this element.
‫So that's here.
‫So this one.
‫So we're selecting now by this class.
‫All right, and we could of course used an id as well here,
‫but that's not really important, okay?
‫What matters here is to now say
‫if there is a log out button,
‫then logOutButton.addEventListener.
‫So we want it to listen to all events happening
‫on that button whenever there is a click.
‫So we're waiting for the click event
‫and when that happens we then call the log out function
‫which we didn't import yet,
‫so let's add that here.
‫So log in and log out.
‫All right, and that should actually be it.
‫So, let's test it now.
‫Reload it again just to be sure,
‫and now
‫Oh, we get error logging out.
‫Try again, why is that.
‫Well, let's try to get a better look at the error.
‫But what's important is that actually all of this
‫is already working.
‫So this event listener here
‫and also this log out function is kind of doing its job.
‫So let's just do
‫console.log error.response.
‫So let's reload this here.
‫Should kind of happen automatically.
‫All right.
‫So try that again.
‫So what is happening here
‫so cast to object id failed for value log out.
‫So that's very weird.
‫Take a look at that route.
‫Oh, of course,
‫that's a serious mistake.
‫Should be log in of course.
‫Okay, but this kind of course, again, happen all the time.
‫So let's reload this here.
‫And try this again.
‫And now we're getting something here.
‫Now it's still and error,
‫but that's no problem at all.
‫So we have a JSON web token error
‫because our JSON web token is malformed.
‫And so it's coming, as you can see,
‫from the is logged in middleware.
‫And so we can kind of guess why that is, right?
‫So let's go back add our auth controller.
‫And so the JSON web token that we're basically
‫sending now is this here, right?
‫So this logged out.
‫And so then here in
‫the isLoggedIn that will then basically trigger an error.
‫So here in JSON web token verify, right?
‫And since this entire function here is wrapped
‫in this catchASync it will send this error down to all
‫global error handling middleware.
‫And that will then create this error which in this case
‫we do not want, remember?
‫So in this isLoggedIn middleware we do not want
‫to cause any errors.
‫And so, let's actually fix that
‫and so we're going to remove this catchASync from here
‫because we do not want to catch any Async errors.
‫Instead what we want to do is to basically
‫catch them locally
‫and then if there's an error simply say next.
‫Like this, okay?
‫So let's do that.
‫So wrap all of this into a try.
‫Close it here.
‫Well, something else wrong.
‫Ah! Probably we are just missing the catch block.
‫And so in this case we want to go to the next middleware.
‫So basically saying that there is no logged in user.
‫Right?
‫So, let's test it again.
‫Go back, oh , and now we're no longer logged in.
‫So log in.
‫That was successful.
‫And now straight away let's log out.
‫Ah! Beautiful! Now it works correctly.
‫And so this time what happened here is that of course
‫this verification here failed
‫because that JSON web token was not in a format that
‫this algorithm expected.
‫But what happened in this case is that the error was
‫not catched using our catchASync function
‫but instead it then went straight to catch err,
‫which then went straight to the next middleware.
‫All right, great!
‫So if we now take a look at our cookies,
‫well we have one in use that probably has already expired.
‫So you see it only has this life of 10 seconds
‫and so if I reload this page now actually
‫then is should already be gone.
‫So you see zero cookies in use.
‫Okay, and that's actually all we have to do
‫in order to log out the user from our website.