‫Next up, we're gonna implement the actual login
‫and log out functionalities in the application.
‫But before we go do that, I should probably mention
‫that when you build your own applications,
‫you should never ever do this,
‫so you should never have a fake user in your code like this
‫which contains the plain word password,
‫because with this, everyone who inspects your code
‫can get access to your application.
‫All the code that you write inside your React application
‫will be available on the front end,
‫so the browsers will download it.
‫And so, any malicious attacker will be able
‫to find this combination of email and password
‫in your source code.
‫And so then, they will get access to your application.
‫Again, never, never do this.
‫We are just doing it here
‫because I just want you to learn the mechanics
‫of authentication in isolation,
‫so basically without having all that stuff,
‫like an actual API call and implementing your own database
‫and all that, like we will do later.
‫All right, but with that out of the way,
‫I now want you to come to this user.JSX file
‫because I want to suggest to you
‫that you actually implement this lecture
‫on your own as a challenge.
‫Down here, I basically have the match plan for this lecture,
‫so the five things that we will need to do
‫in order to implement what we want to implement
‫in this video.
‫And so again, if you'd like, you can now post the video,
‫read through these instructions,
‫and then implement them on your own.
‫Again, that's a very nice opportunity for you to practice
‫and for you to implement part of this feature
‫actually on your own like you will have to do in the future
‫in your job or even when building your own applications.
‫If you'd like, just pause the video now
‫and I meet you back here.
‫All right, so, how did it go?
‫I hope that wasn't too hard.
‫And let's now finish the first step of the five,
‫which is the easiest one,
‫so which is to provide the AuthProvider,
‫so the AuthContext, to our entire component tree.
‫Let's do that out here.
‫AuthProvider, I think that's what it's called, no?
‫Yeah, but somehow it's not being imported,
‫so let's just duplicate this here.
‫Auth, and here, it's called FakeAuthContext.
‫All right, and let's grab this, put it here
‫all the way in the end, and there we go.
‫Now, the order of these two here
‫doesn't really matter in this case,
‫so it could also be like this.
‫Now in some situations,
‫we might actually need inside the CitiesProvider
‫some state from the AuthProvider,
‫which would perfectly be possible.
‫We could, of course, call that custom hook from here
‫also inside the CitiesProvider.
‫And so, in that case, the AuthProvider
‫really would have to be the parent of this one,
‫but in this case, it doesn't really matter.
‫But anyway, let's now come to our actual login page here
‫so that we can now handle clicking here on this button,
‫so basically, when the user submits this form.
‫And first of all,
‫here we now want to get that actual button,
‫so the component that we created earlier,
‫of the type primary and then login.
‫Let's come here, and that looks a lot nicer.
‫And notice how here we already have these values predefined
‫so that fake email, enter fake password,
‫just so we don't have to type them
‫over and over again while testing.
‫And I also already set up our form here,
‫which is two state variables, and of course,
‫with our controlled elements like we already know how to do,
‫so there's no need to type the same thing
‫over and over again.
‫Now here, we will create a handle submit function like this.
‫Let's place that out here.
‫Function.
‫And so, this receives the event object
‫so that, as always, we can do our preventDefault.
‫All right, and then here is where we will want
‫to call that login function, but we only want to do it
‫if the email and password are actually set,
‫so if we have an email and a password,
‫then we want to call the login function.
‫Let's grab that from our context.
‫Login from useAuth.
‫And then here, let's then paste in the email
‫and the password.
‫Exactly the email and passwords that we need,
‫then inside the login function
‫to check if they are the same as this and this one.
‫Now, what's wrong in here?
‫Cannot destructure the login out of useAuth,
‫so probably there are some buck error like,
‫oh yeah, of course, I forgot to then return the context.
‫And so, this is good
‫that you see that everyone makes mistakes.
‫I wasn't copying the code here from anywhere.
‫And so, then I forgot to return that context value there.
‫All right, so with this,
‫we are now ready to actually log in.
‫We click and nothing happens,
‫but also, nothing is supposed to be happening.
‫Let's just check our state, so in the AuthProvider,
‫because here, it actually has changed,
‫so we see that we now are authenticated
‫and the user is set to that fake user,
‫so we were actually successful.
‫And so here, on this page, we should now check
‫whether the isAuthenticated state is now true.
‫And if it is, we want to redirect the user to the app,
‫so to slash app right here.
‫And so, that's why I told you
‫in this step number three, exactly here,
‫so that inside an effect, we need to do this check.
‫And if so, we navigate to app.
‫Let's do that by including a useEffect.
‫Creating our function.
‫And then here, what we want to check
‫is whether the isAuthenticated state has changed.
‫Basically, we want to run this effect
‫where we redirect the user each time
‫that this state here has changed.
‫Then we also need to get that from our context, of course,
‫so isAuthenticated.
‫And so now, let's just say, if isAuthenticated,
‫then we want to navigate to that page.
‫And so for that, we need to grab the navigate function
‫from React Router.
‫That's, again, the programmatic navigation
‫that we have talked about before.
‫Let's see.
‫Navigate to slash app.
‫Now here, we also need the navigate function.
‫And you see that it actually immediately redirected us
‫here to this app.
‫Let's just reload this,
‫so go to the beginning, reload, come here,
‫but apparently we have a buck,
‫so that should not be happening.
‫Let's try that again.
‫Ah, but actually it's because here,
‫we are directly going to slash app,
‫so we should change that here as well.
‫But for now, let's just check.
‫Here we come to log in.
‫And so now, let's change just email here to something wrong.
‫And so then, when I click, nothing happens.
‫In this situation, we actually would want
‫to display some message here, so somewhere on the screen,
‫telling the user that login was not successful.
‫We can add some other piece of state here,
‫like an error or so,
‫and then display that error to the user.
‫But again, here we just want to keep it simple.
‫Now, let's test the correct case.
‫And beautiful.
‫That worked.
‫Our fake login is actually working right now.
‫And so, this part here, so this effect has two big purposes.
‫First of all, when the user successfully authenticates,
‫then, of course, after this function has been called,
‫the isAuthentic state will change to true.
‫And so then, this component will re-render,
‫and then in this effect, this will already be true,
‫and then we navigate to the application.
‫While in the beginning, this is still false.
‫On the initial render, this effect will also run,
‫but then this here is still false.
‫And so then, we don't navigate to the application.
‫Now, the nice side effect of that is
‫when the user is already authenticated
‫but then clicks on login,
‫they will automatically and immediately
‫get redirected to the app itself.
‫You saw that.
‫Now, watch what happens when we click here on back.
‫That doesn't work at all.
‫And the reason for that is that it keeps going back
‫to the login page, but since we already logged in,
‫it keeps redirecting us to this page.
‫Again, when we click here, it goes back,
‫but then immediately, it goes forward again.
‫Now, if we reload this here and log in again,
‫yeah well, then the same thing is gonna happen.
‫Always the same problem.
‫The solution to this is to not even go back
‫to the login page, but instead,
‫really replace that we have ever been there.
‫We can do that by specifying an object
‫with the replace option set to true.
‫And so then, in this case, once this navigation happens,
‫it will replace the login page
‫in the history stack with just this one.
‫Let's try this once again.
‫Login here, and then as we go back,
‫it just goes back to where we were before the login page,
‫so it has overwritten basically that we were ever there.
‫And so, this part here is very important
‫to make the browser work as usual,
‫so in the way in which the user is familiar.
‫Now okay, so we're already running a bit long,
‫but this part is finished.
‫And so now, let's very quickly
‫create the logout part as well.
‫From our instructions, remember that we
‫should come here to this component
‫and then read the logged-in user and display it.
‫Now, we can actually get rid of this fake user.
‫And then, let's read user from useAuth like this.
‫And this should already be enough
‫because all the JSX code has already been written for us,
‫so let's now come to the app layout
‫and then I will just include that here after the map.
‫User like this, doesn't need any props.
‫And there it is.
‫Nice.
‫And so, this data is, of course,
‫now coming from our fake user.
‫If I change the name there...
‫like where is that?
‫Then it should change to Jonas right here,
‫which didn't really work, but if we do this again,
‫then there it is.
‫That's our fake logged-in user right there.
‫And so now, all we have to do
‫is to make that logout button work.
‫That shouldn't be too hard
‫because we already have our logout function.
‫Let's grab that from the context
‫and then here we can simply call that.
‫Just logout.
‫However, if we do this now,
‫then nothing is really gonna happen.
‫I mean, the user here will disappear,
‫but we will stay on this page.
‫Watch what happens.
‫And so, we actually get an error
‫because we are then trying to read all this data here
‫from the user that no longer exists,
‫so we set the user back to null,
‫and so then, of course, all these properties doesn't exist
‫or don't exist.
‫And so then, what we need to do
‫is to redirect again to the homepage.
‫Const navigate.
‫And so here, more and more,
‫you see the programmatic navigation in action,
‫'cause this, of course, cannot really happen
‫just by the user clicking.
‫We first need to log out the user
‫and then we can navigate to slash app.
‫All right, so let's try that again.
‫And so, that also doesn't work
‫and that's because we are still here in cities.
‫In slash app...
‫and actually, let's now change here the link
‫from app to the login page.
‫We can now only really reach the application
‫by going through the login page.
‫Let's do that.
‫That still works.
‫And now, as we log out,
‫well, we still have some problem here,
‫but yeah, I don't even need to read that
‫'cause I just noticed that, of course,
‫we want to redirect to the homepage.
‫We are out of the app, of course.
‫Maybe you spotted
‫that it's actually in the instructions.
‫And beautiful.
‫Great.
‫Let's try that again because now I want to show you
‫what happens when we try to basically open this page
‫without being logged in.
‫That's what's gonna happen when we just reload the page.
‫If we try to just enter this URL
‫without first going to the login flow,
‫then we get this error.
‫And so, we need to prevent that
‫by basically protecting our application
‫against unauthorized access.
‫And so, remember from the very beginning,
‫that that is the third part
‫of a typical login flow in front end applications.
‫And so, let's implement that in the next video.