Let's create a generic component that will be displayed when the user passes validation. The file is named Secure.vue
, and add the following to go in:
<template> <div>
Open the ./src/App.vue
file and add the following in:
<template> <div id= "app" > <div id= "nav" > <router-link to= "/" >home</ router-link> | <router-link to= "/about" >about</router-link><span v-if= "isLoggedIn" > | <a @click = "Logout" >Logout</a></span> </div> <router-view/> </ Div></template>
If the user logs in, can you see the associated? Logout
Very good.
Now, let's add logic to logout.
<script> Export Default { computed: { isloggedin:function () {return this.$ Store.getters.isLoggedIn} }, methods: { logout:function () {this . $store. Dispatch (' logout ') . Then (() = {this . $router. Push ('/login ')}}} , }</script>
When the user clicks the Exit button, we are actually doing two things-calculating the status of the user verification and distributing the exit event inside the Vuex store. After exiting, we use this.$router.push('/login')
, switch the user to the login
page. Of course you can change any place you want users to jump to.
That's it. Let's build the Permissions module with Vuex.
Vuex Permissions Module
If you have read the previous Setup node. js Server section, you should note that we need to store user rights tokens locally, and when the user is granted permission, we need to get token and user information back at any time.
First, let's create a file for Vuex store.js
:
Import vue from ' Vue ' import Vuex from ' Vuex ' import Axios from ' Axios ' Vue.use (VUEX) export default new Vuex.store ({ stat E: { status: ', token:localStorage.getItem (' token ') | | ", User: {} }, mutations: {} , actions: { }, getters: {} })
If you notice that we've introduced both Vue,vuex and Axios, then let Vue use Vuex, because it's an important step.
We have defined the properties of state. Now the state of Vuex can support authentication status, jwt
token, and user information.
creating Vuex Logon events
The Vuex actions are mostly submitted to the Vuex store. We will create an login
action that will use the server to authenticate the user and submit user credentials to the Vuex store. Open the ./src/store.js
file and add the following to the actions object:
Login ({commit}, user) { return new Promise ((resolve, reject) = { commit (' auth_request ') axios ({url: ') Http://localhost:3000/login ', Data:user, Method: ' POST '}) . Then (resp = { Const token = Resp.data.token Const USER = Resp.data.user localstorage.setitem (' token ', token) axios.defaults.headers.common[' Authorization '] = token commit (' auth_success ', token, user) Resolve (RESP) }) . catch (Err = { commit (' Auth_error ') localstorage.removeitem (' token ') reject (Err) })} ,
The login action is commit
validated by Vuex and we will use it to trigger the change. These changes can be recorded in the Vuex store.
We are calling the server's login path and returning the necessary data. We store tokens locally and then update the auth_success
Stored user information and tokens. At this point, we also set up in the head axios
.
We can store tokens in the Vuex store, but if the user leaves our app, all the storage in Vuex will disappear. To ensure that users do not have to log in again during the effective time, we can only store tokens locally.
The important thing is that you know how this works, so that you can decide what you want to achieve.
We return a promise so that we can respond when the user logs in.
Create Vuex 注册
event
Like login
events, the register
event is the same way of working. In the same file, add the following to the actions object:
Register ({commit}, user) { return new Promise ((resolve, reject) = { commit (' auth_request ') axios ({URL : ' Http://localhost:3000/register ', Data:user, Method: ' POST '}) . Then (resp = { Const token = Resp.data.toke n Const user = Resp.data.user localstorage.setitem (' token ', token) axios.defaults.headers.common[' Authorization '] = token commit (' auth_success ', token, user) Resolve (RESP) }) . catch (Err = { commit (' Auth_error ', err) Localstorage.removeitem (' token ') reject (Err) })} ,
It login
works much like the way events work. It's called having a common mutators login
and register
having the same goal-getting users into the system.
Create Vuex 退出
event
We want the user to be able to exit the system, and we want to destroy the last validated session data. In the same actions
object, add the following:
Logout ({commit}) { return new Promise ((resolve, reject) = { commit (' logout ') Localstorage.removeitem (' token ') Delete axios.defaults.headers.common[' Authorization '] resolve ()} )}
Now, when the user clicks to exit, we will remove the token that was previously set in the axios
header jwt
. They will now be unable to perform transactions that require tokens.
Create Mutations
As I mentioned before, mutators is used to change the state of the Vuex store. Let's define the used mutators in the application. In the Mutators object, add the following:
Mutations: { auth_request (state) { state.status = ' loading ' }, auth_success (state, token, user) { state.status = ' success ' State.token = token state.user = user }, Auth_error (state) { State.status = ' ERROR ' }, logout (state) { state.status = ' State.token = '}, },
Create getters
We use getter to get the value of the attribute in the Vuex state. In this case, the Getter's role is to separate the application data from the application logic and ensure that we do not disclose sensitive information.
Add the following to the getters
object:
Getters: { isloggedin:state =!! State.token, authstatus:state = State.status,}
You will agree with me that this is a more concise way to access stored data ️.
hide a page behind auth
The whole purpose of this article is to implement authentication so that users without permissions cannot see certain pages. To achieve this, we need to know which page the user wants to access, and when the user is authorized, we have a way to verify it. We also need certain ways, if certain pages, authorized or unauthorized users can be accessed individually or concurrently. These are important considerations, fortunately, we can do it through vue-router.
define routes to authorized and unauthorized pages
Open the ./src/router.js
file and introduce the things we need:
Import vue from ' Vue ' import Router from ' Vue-router ' to ' import store from './store.js ' import Home from './views/home.vue ' Impor T about from './views/about.vue ' import Login from './components/login.vue ' import Secure from './components/secure.vue ' Import Register from './components/register.vue ' Vue.use (Router)
As you can see, we've introduced Vue,vue-router and the Vuex we created. We also introduced all of the defined components and set up the use of routing in Vue.
Let's define the route:
[...] Let router = new Router ({ mode: ' History ', routes: [ { path: '/', Name: ' Home ', component:home }, { path: '/login ', name: ' Login ', component:login }, { path: '/register ', name: ' Register ', component:register }, { path: '/secure ', name: ' Secure ', Component:secure, meta: { requiresauth:true } }, { path: '/about ', name: ' About ', component:about } ]}) export default router
The definition of our route is very common. For a route that requires permission validation, we need to add additional data to ensure that we can identify it when the user accesses it. This is the essence of the meta-attribute added to the route definition. If you want to ask, "Can I add more data to the metadata and use it?", I am very determined to tell you that this is absolute.
Troubleshooting unauthorized Access Examples
We have our own route definition. Now, let's examine unauthorized access and take action. In the router.js
file, add the following export default router
before:
Router.beforeeach (to, from, next) = { if (to.matched.some (record = Record.meta.requiresAuth)) { if ( Store.getters.isLoggedIn) { next () return } next ('/login ') } else { next () }})
From this article, by using Vue router for authentication, you can recall that we have a very complex mechanism here, which becomes very large and becomes very confusing. Vuex has helped us simplify it, and we can continue to add any conditions to the route. In our Vuex store, we can define operations to check these conditions and get the values that return them.
example of resolving token expiration
Because we store tokens locally, it can be preserved all the time. This means that whenever we open our app, it can automatically authenticate the user, even if the token has expired and expires. Most of the situation, our request will continue to fail because of invalid token. This is a bad experience for the user.
Now, open the ./src/App.vue
file and inside the script, add the following:
Export default { [...] Created:function () {this . $http. Interceptors.response.use (Undefined, function (err) { return new Promise ( function (Resolve, reject) { if (err.status = = = 401 && err.config &&!err.config.__isretryrequest) { C5/>this. $store. Dispatch (Logout) } throw err;});} )
We intercepted the Axios request and determined if the response was obtained 401未授权
. If we do, we distribute logout
the event, then the user gets out of the app. This will let the user jump to the previously designed login
page so they can log in again.
I agree that this will enhance the user experience ️.
End
From the previous article, you can see that, based on the introduction of Vuex, our current application has undergone significant changes. Now, we don't rely on checking tokens all the time, and there are chaotic conditions wherever we go. We can simply use the Vuex store to manage permissions, and only use a few lines of code to check the state in the application.
I hope this will help you build a better application.