تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Planning Route Middleware0:00

Let's take a look at how we can make use of middleware to protect certain routes. So for example, for login and register, we only want to be able to access these routes if we are not logged in. And for myinfo and create, we only want to be able to access these routes if we are logged in. So there is a section in the docs for middleware. Basically we can create files in the middleware directory, maybe one for auth and maybe one for guest. And the pages we want to use them, we can use define page meta. And there should be an example here of how to format the middleware file.

Building Auth Middleware0:27

And the pages we want to use them, we can use definePageMeta. And there should be an example here of how to format the middleware file. So let's go ahead and do that. So let's grab this. Let's make a middleware for auth and guest in our application here. So let's say new file, middleware, let's name it auth.js or TypeScript if you like. Let's paste that in. You can see we have access to the current route or the route we're coming from in these params here. But in our case, we don't need this.

params here. But in our case, we don't need this. So let's get rid of this. We just need a way to check if we are logged in. And for now, let me just hard code this to show the middleware working. So let's say isLoggedIn, let's say false for now. And then we can say if, if we're not logged in, so if not isLoggedIn, then go ahead and redirect to the login page. So we can do return navigateToLogin. Or like I've been doing in the last video, I'm just going to do a full page redirect.

So we can do return navigate to login. Or like I've been doing in the last video, I'm just going to do a full page redirect. So I'm going to use window.location.pathname equals login, okay. So now if we wanted to add this on a certain page, we can do that like this, definePageMeta. So let's add it to our MyInfo page for now. So let's go to that page. Let's put it at the top of the script here, paste that in. And we do have this auth middleware. So let's save that.

And we do have this auth middleware. So let's save that. And now, if I try to hit My Info, remember, we hard coded false as isLoggedIn, in our middleware here. So it should redirect back to the login page. So if we try going to My Info, that doesn't seem to work, we might have to restart our server here. Okay, let's try going to My Info. And we are redirected back to login, because we're currently not logged in. Now if I try to go to My Info manually in the title bar here, we are going to get an

Adding Guest Middleware2:57

Let's do something similar for a guest middleware, and make sure that works on these pages here. So basically the same thing. Let's duplicate this. Let's say guest. And it's just the opposite here. So if we are logged in, then redirect to the MyInfo page. Let me just add this here as well. And let's change the isLoggedIn to true, to see that work. Let's make sure to also set the auth to true as well, or we might have an infinite redirect. Okay.

Let's make sure to also set the auth to true as well, or we might have an infinite redirect. Okay. Oh yeah, I forgot to add it to the login page. So let's do that. Let's grab this definePageMeta. Let's put it on the login page, right here. And let's say middleware('guest'). Okay. Let's try this out. If I try to go to login, it should redirect to the My Info page.

Let's try this out. If I try to go to login, it should redirect to the My Info page. And it does. Cool. So let me just make sure to add these to all the pages. So we want this on our register page as well. So let's put it in here. Okay. And we also want it on our create page. So this is middleware auth.

Tracking Auth via LocalStorage4:06

And we also want it on our create page. So this is middleware auth. Okay. So now we need a way to detect if we are logged in or not. Right now I'm just hard coding true or false. So how do we do that? There are a few ways to do this. The way I like to do it is store a variable in localStorage if we're logged in that holds some user information. So if we are logged in, that localStorage variable should exist.

some user information. So if we are logged in, that localStorage variable should exist. And if we're not, then it shouldn't exist. So I'm going to store all of the logic for getting and setting the localStorage variable within a composable. So let's do that. Let's say new file, composables, and let's name it useAuth.js. And this will export a function named useAuth. Okay. And let's define a few methods here.

Okay. And let's define a few methods here. Let's define one for setting that variable in localStorage. So setUser. We need a name. And we can say localStorage.setItem. Let's name it user for the key. And the value is just going to be an object with whatever user information you want. So in this case, I'm just going to store the user's name. So let's stringify that.

So in this case, I'm just going to store the user's name. So let's stringify that. JSON.stringify the name coming in. Okay. And that should be fine. Let's make a method for getting that user. So let's say getUser. And let's return that user. So return JSON.parse. So we want to turn it back into an object when we're grabbing it.

So return JSON.parse. So we want to turn it back into an object when we're grabbing it. So localStorage.getItemUser. Okay. Let's make a method for removing that from a localStorage. So let's say removeUser or deleteUser. Okay. And we're basically just calling removeItem. And the key is user. And now I'm going to make a computer property here that just checks if this item exists.

And the key is user. And now I'm going to make a computed property here that just checks if this item exists in local storage. So let's say const isLoggedIn equals computed property. And let's say return localStorage.getItem('user'). So if it exists, it will be a truthy value. And if it doesn't exist, it will be null, which is false or falsy. Or if you want to convert it to a boolean, you can just do two exclamation marks here. Okay. So let's make sure to return what we need to use.

Okay. So let's make sure to return what we need to use. So let's return these methods. So setUser, getUser, removeUser, and isLoggedIn. Okay, save that. So before we update our middleware, let's try to make use of this when we're logging in. Actually, let me remove the middleware for now on the login page. Actually, let's remove it for both for now. So let's just make it an empty array.

Actually, let's remove it for both for now. So let's just make it an empty array. And also on the MyInfo page. Okay. Now, when we log in, let's make sure to set that variable in localStorage. So after we're logged in here, so we can grab that setUser method that we just created. So let's say const setUser. We can grab that from our composable, useAuth. And we can set the user in here. So setUser.

And we can set the user in here. So setUser. And we need the user's name here. That info doesn't come back from the login endpoint. But we do have that other endpoint that grabs the user's information. So let's grab it from there first. So let's say const user equals await API.fetch('/api/user'). And now we should have that user's name, user.name, okay. And when we log out, let's make sure to remove that variable from localStorage. So let's grab this.

And when we log out, let's make sure to remove that variable from localStorage. So let's grab this. Let's go to our default view. So here's the logout method. Let's make sure to import that first up here. We actually want to remove user. Okay, and then we can call it down here. So let's call it in the finally clause because we want to remove the user in both cases. So remove user, okay. And hopefully that does it.

So remove User, okay. And hopefully that does it. So let me save this. Go back to our app. And right now I am not logged in. So let me open up DevTools here. If I refresh this page, you can see we are getting unauthorized because we're not logged in. And obviously there should be nothing in local storage at this point. Right here.

And obviously there should be nothing in local storage at this point. Right here. Okay, there's no user here. So let's see if it does add it to local storage after we log in. So we'll try logging in here. Okay, we are redirected to the My Info page. And you can see the user variable within local storage. Okay, so that is working. Let's make sure logout works as well. So let's see if this key gets deleted when I log out.

Let's grab this. Let's go to register. And we can do the same thing in here. So after we register. So after this, we can set that key in localStorage. So let's do that here. And I think we do get the user's name after we register here. Let's double check. const user equals that. And hopefully this works.

Cost user equals that. And hopefully this works. So let me just refresh. Let's go to the register page here. Actually, I have the middleware on for that. So let me remove that on the register page up here. Let's get rid of that. And let's go ahead and register a new user here. So let's make sure that it does add that variable after we register here. And it does not.

So let's make sure that it does add that variable after we register here. And it does not. So it looks like register doesn't return the User. So let me just log out. That should delete this. And we can do what we did on the login page. So let's get rid of this since it doesn't return anything. Let's grab the endpoint from login. So we need to grab the User information. And let's just make sure to call it right here.

So we need to grab the User information. And let's just make sure to call it right here. Okay, so let's try that again. Let's make a new User here. And let's see if it adds the correct variable with their name in local storage. And it looks like it does. Cool. So now that we have our local storage in place, that can keep track if we're logged in or not. So let's update our middleware here.

not. So let's update our middleware here. Let me actually put them back for all of our pages. So this one is guest. Same for login. Up here, make sure it's set to guest. And same for myInfo. But this one is off. Okay. So now in our actual middleware, we can make use of that isLoggedIn variable coming from.

Okay. So now in our actual middleware, we can make use of that $isLoggedIn variable coming from our useAuth composable. So let's say $isLoggedIn, coming from useAuth. And we can do the same for the other middleware. Okay, save that. And back to our app. So right now I am logged in. Let's go back to the homepage. Let me just refresh to make sure.

Let's go back to the homepage. Let me just refresh to make sure. So I should be able to access my info and create and I can. Cool. But when I hit register or login, that should redirect back to my info. And it does. Cool. Okay. However, we still have the same issue I showed you earlier on, when we try to go to that route directly.

Fixing SSR Client-Only Code12:14

However, we still have the same issue I showed you earlier on, when we try to go to that route directly. So if we try to go to login, we're going to get an error here. It says window is not defined. Like I said earlier, a few things are not available on server side JavaScript, but are available on client side JavaScript. So for example, window and also localStorage is only available on the client side. So what we want to do here is only run some of this code on the client. So let's start here in our composable. Like I said, localStorage is only available client side.

So let's start here in our composable. Like I said, localStorage is only available client side. And we can actually check if we're on the client using process.client. So let's put a conditional in here. So if process.client, so let me just make sure to wrap this correctly. Okay, save that. And if it's on the server, nothing is going to happen. But eventually the client will run this code. So let's do the same for our middleware here. So let's grab this.

So let's do the same for our middleware here. So let's grab this. Let's go to our auth middleware. And we can wrap this in that same conditional. So again, only run it in the client. If it's on the server, do nothing. And eventually the client will pick it up. Okay, do the same for our guest. Okay, save that. And hopefully everything is working now.

Okay, save that. And hopefully everything is working now. So let's try all cases here, I might have to restart my server. So I'm currently logged in. So the myInfo and create pages should work. myInfo, create, let's try putting it directly in the address bar here. Okay, that works. Make sure create works as well. Okay, so if I try to go to login or register, that should redirect back to myInfo. Okay, that works.

Let's try the opposite case when we're not logged in. So let me log out here. Okay, now register and login should work. And that doesn't seem to work. Let's try register here. Actually, that's not working because isLoggedIn is a ref, and we have to use dot value to reference it. So let's update our middleware. Also our auth, make sure to say dot value here. And let's double check everything again.

Also our auth, make sure to say value here. And let's double check everything again. So right now we're not logged in. So if I try to hit myInfo or create, it should redirect back to login and it does. Let's try putting it in here. It does redirect. Cool. And if we hit this directly, this should work as well. And let's double check the case when we're logged in as well. So let me just log in.

And let's double check the case when we're logged in as well. So let me just log in. Okay, now I'm logged in. If I try to hit login or register, that redirects. And same for when I try to type it in here. And it does. Cool. So everything is working. Now let's work on showing and hiding these menu items based on if we're logged in or not.

Conditionally Rendering Menu Items15:23

Now let's work on showing and hiding these menu items based on if we're loggedIn or not. So should be pretty straightforward since we have this isLoggedIn value. So let's go to defaultView. Actually, let me grab this. Let's go to defaultView. Make sure to import that here. Or we can grab it from here actually isLoggedIn. And we can just make use of this in our menu items. So up here.

And we can just make use of this in our menu items. So up here. So these two login and register should only show if we're not logged in. So let's say v-if equals !isLoggedIn. And these two should be if we are logged in. v-if equals isLoggedIn. Okay. Actually for logOut as well. So let's grab this. Put it for logOut.

So let's grab this. Put it for log out. Save this. And let's see if those menu items are showing correctly. So right now we are logged in. So register and login is not showing. And if we log out, my info and create are not showing. So everything is working. So let me just log in here. I think sometimes we might get warnings about some hydration issues.

So let me just log in here. I think sometimes we might get warnings about some hydration issues. And you can see in the console here that we have a hydration node mismatch. This means that the markup coming back from the server does not match the markup in the client. So like we were doing earlier, we just want to render some things on the client. So in this case, if you want to fix that warning, we can wrap this entire menu in a client-only component. So let me grab this. Okay.

So let me grab this. Okay. And now hopefully that warning is gone. So let me save that. Let's go here. And that warning is no longer there. So these menu items are only being rendered on the client. I think one more thing I forgot to show you is to make use of the user within the local storage. We are using it to track if we're logged in or not.

storage. We are using it to track if we're logged in or not. But if there are parts of the app that need that information, instead of grabbing it from the server, we can just grab it from localStorage. So for example, we are storing the name in localStorage. So if you wanted to show the name, say in the menu here, let's do that. So let's say, getUser, and let's use optional chaining because it might be null sometimes, .name. And let's make sure to grab that user from here. And if you don't remember, that comes from our useAuthComposable.

And let's make sure to grab that user from here. And if you don't remember, that comes from our useAuthComposable. So right here, just grabbing it from localStorage. So let's try that out. There's our name. But if we log out, it doesn't show here. Cool. So yeah, if you need to protect your routes, definitely make use of the middleware available in Nuxt. So as always, let's make a commit.

in Nuxt. So as always, let's make a commit. Let's say git add, git commit middleware.

Setting up Middleware in NuxtUsing localstorage to keep track of logged in status

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟