In this lesson, we're going to create and protect a new page by requiring users to authenticate with a login form. Normally, we would have to check if the user and password match those that are in a database and allow the user to sign into. But for now, we'll just fake that part. To protect our roots, we can use global navigation guards.
You can consider navigation guards as traditional middleware hooks that we can run before or after entering a root. To define global guards, we need to access the router instance. Therefore, we need to store the router as a variable and export it instead. beforeEach.
beforeEach accepts a callback function which receives the to, the from, and the next arguments. We want to have a user page that you can only access if you are a user. js file. Make sure to put it above the not found route as the path of asterisks will match any path therefore if we put the user route after it it will always match the not found route and never show the actual route we want to show.
Now how would we be able to tell the route guard that a route should be protected? Vue Router supports something called metafields, which we can include when defining a root. Let's add a meta attribute to the user root to mark the root as protected. I'll call it requiresAuth and set the value to true.
Keep in mind that the meta property expects an object and that we can put whatever we need in that object. With the metafields, we can create advanced root logic for our needs. for instance to prevent an action based on permission or as we do now by requiring authentication. meta.
Let's check if the to root, the root we are going to, has a meta of requires auth and if it does we will require the user to log in before they visit the page. In order to log in we need to create a login page that contains a form with an input and a label for our username and password and a button. We can use the vModel directive with the value of username and password so that we can bind these values to our data. Then in our data, we can set the values of username and password to null.
We can then add a click event to our button, which we'll call the login method when it is clicked. In this lesson, we will not perform the actual authentication in a real-world application This is where we would authenticate the user against our API. For now, we'll pretend that the user is successfully authenticated and store the username in our store. And of course, in order to use the store, we will have to import it.
Then in our login method, we can update the value of user coming from the store to be the value of our username coming from our login form. push. To finish off our login, we should add some styles to the form to make it look a little nicer. view as these are more general styles that can then be used throughout the whole app.
js file, we need to add our root for the login page. Then we can check if the user is authenticated or not. So if we don't have the user in our store, we have to redirect them to the login page. We can do that by calling next.
with the name of the component where we want the user to be redirected to. Otherwise, if the user is authenticated, we'll just call next to continue with the regular flow. Each root object in the roots configuration is called a root record. Root records may be nested, so if a root is matched, it can potentially match more than one root record.
For example, if we were to add a metafield to the experiences root, it would also match the destinations root. as experiences is a child of destinations. matched property. We can then use the sumJavaScript method which tests whether at least one element in the array passes the test.
requiresAuth, then we need to log in. We can now add the root to our navigation component by adding a router link that goes to the user root. Now if we check to see if it works you will see that clicking on the dashboard link does not take us where we want to go. Let's see if we have any errors.
Hmm, root with name slash login does not exist. Let's check our code to see what is happening. In our before each guard we have called the name of our component with a slash. The slash is what we use for the path but the name shouldn't have a slash.
So let's remove it. Our root now works. Also, did you notice that we have used the user for our webpack chunk name in the login component? That won't cause a problem with the root, but we'll add the login chunk to the user chunk, meaning every time we go to the login page, we will download the JavaScript needed for both the login and the user page.
We don't really want that as the user might not log in therefore we don't need to download any extra JavaScript. Let's change it to login. Now let's try to access our user page without logging in. You will see we are redirected back to the login.
Great! Before we fill in the form you will see that a username label isn't showing. Let's fix that first. If we click submit without adding a username we will not go to the user page.
However if we do add a username we go straight to the user page and are logged in. Remember we didn't add any logic for the password so it doesn't matter if we fill that in or not. However we are now constantly logged in so let's fix that. In our user page we can create a logout button and we can add a click event with a logout method.
Then in our methods we can create a logout function that resets the value of user that comes from the store to be null. push to redirect the user to the home page. So that we have access to our store, we need to import it. We can also print out a nice welcome message to our user which prints out their name.
user. And as you can see, it works just like it should. We can now log in and log out. In this lesson, we're going to create and protect a new page by requiring users to authenticate with a login form.
Normally, we would have to check if the user and password match those that are in a database and allow the user to sign into. But for now, we'll just fake that part. To protect our roots, we can use global navigation guards. You can consider navigation guards as traditional middleware hooks that we can run before or after entering a root.
To define global guards, we need to access the router instance. Therefore, we need to store the router as a variable and export it instead. beforeEach. beforeEach accepts a callback function which receives the to, the from, and the next arguments.
We want to have a user page that you can only access if you are a user. js file. Make sure to put it above the not found route as the path of asterisks will match any path therefore if we put the user route after it it will always match the not found route and never show the actual route we want to show. Now how would we be able to tell the route guard that a route should be protected?
Vue Router supports something called metafields, which we can include when defining a root. Let's add a meta attribute to the user root to mark the root as protected. I'll call it requiresAuth and set the value to true. Keep in mind that the meta property expects an object and that we can put whatever we need in that object.
With the metafields, we can create advanced root logic for our needs. for instance to prevent an action based on permission or as we do now by requiring authentication. meta. Let's check if the to root, the root we are going to, has a meta of requires auth and if it does we will require the user to log in before they visit the page.
In order to log in we need to create a login page that contains a form with an input and a label for our username and password and a button. We can use the vModel directive with the value of username and password so that we can bind these values to our data. Then in our data, we can set the values of username and password to null. We can then add a click event to our button, which we'll call the login method when it is clicked.
In this lesson, we will not perform the actual authentication in a real-world application This is where we would authenticate the user against our API. For now, we'll pretend that the user is successfully authenticated and store the username in our store. And of course, in order to use the store, we will have to import it. Then in our login method, we can update the value of user coming from the store to be the value of our username coming from our login form.
push. To finish off our login, we should add some styles to the form to make it look a little nicer. view as these are more general styles that can then be used throughout the whole app. js file, we need to add our root for the login page.
Then we can check if the user is authenticated or not. So if we don't have the user in our store, we have to redirect them to the login page. We can do that by calling next. with the name of the component where we want the user to be redirected to.
Otherwise, if the user is authenticated, we'll just call next to continue with the regular flow. Each root object in the roots configuration is called a root record. Root records may be nested, so if a root is matched, it can potentially match more than one root record. For example, if we were to add a metafield to the experiences root, it would also match the destinations root.
as experiences is a child of destinations. matched property. We can then use the sumJavaScript method which tests whether at least one element in the array passes the test. requiresAuth, then we need to log in.
We can now add the root to our navigation component by adding a router link that goes to the user root. Now if we check to see if it works you will see that clicking on the dashboard link does not take us where we want to go. Let's see if we have any errors. Hmm, root with name slash login does not exist.
Let's check our code to see what is happening. In our before each guard we have called the name of our component with a slash. The slash is what we use for the path but the name shouldn't have a slash. So let's remove it.
Our root now works. Also, did you notice that we have used the user for our webpack chunk name in the login component? That won't cause a problem with the root, but we'll add the login chunk to the user chunk, meaning every time we go to the login page, we will download the JavaScript needed for both the login and the user page. We don't really want that as the user might not log in therefore we don't need to download any extra JavaScript.
Let's change it to login. Now let's try to access our user page without logging in. You will see we are redirected back to the login. Great!
Before we fill in the form you will see that a username label isn't showing. Let's fix that first. If we click submit without adding a username we will not go to the user page. However if we do add a username we go straight to the user page and are logged in.
Remember we didn't add any logic for the password so it doesn't matter if we fill that in or not. However we are now constantly logged in so let's fix that. In our user page we can create a logout button and we can add a click event with a logout method. Then in our methods we can create a logout function that resets the value of user that comes from the store to be null.
push to redirect the user to the home page. So that we have access to our store, we need to import it. We can also print out a nice welcome message to our user which prints out their name. user.
And as you can see, it works just like it should. We can now log in and log out.