傳統(tǒng)方式中,許多人使用本地存儲,來管理通過客戶端驗證生成的tokens。一個大問題是如何有更好的方式,來管理驗證tokens,從而允許我們來存儲更大的用戶信息。
寧都網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)公司等網(wǎng)站項目制作,到程序開發(fā),運營維護。成都創(chuàng)新互聯(lián)于2013年成立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)。
這就是Vuex的作用。 Vuex為Vue.js應(yīng)用管理狀態(tài).。對于應(yīng)用中所有的組件來說,它被當(dāng)做中央存儲,并用規(guī)則確保狀態(tài)只能以可預(yù)見的方式改變。
對于經(jīng)常檢查本地存儲來說,聽起來是個更好的選擇?讓我們一起來探索下吧。
建立應(yīng)用模塊
對于這個項目,我們想創(chuàng)建一個使用vuex和vue-router的vue應(yīng)用。我們會使用vue cli 3.0 來創(chuàng)建一個vue項目,并從選項中選擇路由和vuex。
執(zhí)行下面的命令開始創(chuàng)建:
$ vue create vue-auth
按照對話框的提示,添加必要的信息,并選擇我們需要的選項,完成安裝。
下一步, 安裝axios:
$ npm install axios --save
配置Axios
我們在許多組件中都需要用到axios。讓我們在全局整體來配置它,這樣當(dāng)我們需要它的時候,不用每次都去引入。
打開 ./src/main.js 文件,并且添加下面:
[...] import store from './store' import Axios from 'axios' Vue.prototype.$http = Axios; const token = localStorage.getItem('token') if (token) { Vue.prototype.$http.defaults.headers.common['Authorization'] = token } [...]
現(xiàn)在,當(dāng)我們想在組件內(nèi)使用axios時, 我們可以用this.$http
,這樣相當(dāng)于直接是axios。我們也可以在axios頭部給自己的token, 設(shè)置身份驗證,這樣如果token是必需的,我們的請求將處于控制中。在這種方式下,當(dāng)我們想要發(fā)送請求時,任何時候都不用設(shè)置token。
相關(guān)課程: Vue創(chuàng)建一個網(wǎng)上商店
完成之后,讓我們使用服務(wù)器來處理身份驗證。
創(chuàng)建身份驗證服務(wù)
我已經(jīng)寫過關(guān)于這個,在我解釋如何用vue-router來解決身份驗證時。仔細看看Setup Node.js Server 這個章節(jié)。
創(chuàng)建組件
登錄組件
創(chuàng)建Login.vue
在 ./src/components
目錄下。 之后, 給登錄頁面添加模板:
<template> <div> <form class="login" @submit.prevent="login"> <h2>Sign in</h2> <label>Email</label> <input required v-model="email" type="email" placeholder="Name"/> <label>Password</label> <input required v-model="password" type="password" placeholder="Password"/> <hr/> <button type="submit">Login</button> </form> </div> </template>
當(dāng)你做完之后, 添加data屬性,將其綁定到HTML表單中:
[...] <script> export default { data(){ return { email : "", password : "" } }, } </script>
現(xiàn)在, 讓我們給登錄添加方法:
[...] <script> export default { [...] methods: { login: function () { let email = this.email let password = this.password this.$store.dispatch('login', { email, password }) .then(() => this.$router.push('/')) .catch(err => console.log(err)) } } } </script>
我們正在使用vuex的action — login 來解決身份驗證。我們可以在將actions細化到回調(diào)里面,這樣就可以在自己的組件里面做一些很酷的事情了。
注冊組件
跟login組件類似,那我們給注冊用戶弄一個了。在組件目錄里面創(chuàng)建Register.vue ,并將下面的添加進去:
<template> <div> <h5>Register</h5> <form @submit.prevent="register"> <label for="name">Name</label> <div> <input id="name" type="text" v-model="name" required autofocus> </div> <label for="email" >E-Mail Address</label> <div> <input id="email" type="email" v-model="email" required> </div> <label for="password">Password</label> <div> <input id="password" type="password" v-model="password" required> </div> <label for="password-confirm">Confirm Password</label> <div> <input id="password-confirm" type="password" v-model="password_confirmation" required> </div> <div> <button type="submit">Register</button> </div> </form> </div> </template>
讓我們定義一下這些將綁定到表單里面的data屬性:
[...] <script> export default { data(){ return { name : "", email : "", password : "", password_confirmation : "", is_admin : null } }, } </script>
現(xiàn)在,讓我們添加方法進去:
[...] <script> export default { [...] methods: { register: function () { let data = { name: this.name, email: this.email, password: this.password, is_admin: this.is_admin } this.$store.dispatch('register', data) .then(() => this.$router.push('/')) .catch(err => console.log(err)) } } } </script>
安全組件
讓我們創(chuàng)建一個普通的組件,它在用戶通過驗證后會顯示。文件命名為Secure.vue,并添加下面的進去:
<template> <div> <h2>This page is protected by auth</h2> </div> </template>
更新App組件
打開./src/App.vue 文件,并添加下面的進去:
<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>
如果用戶登錄進去后,你能看到關(guān)聯(lián)的Logout了 嗎?很好。
現(xiàn)在,讓我們給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>
當(dāng)用戶點擊退出按鈕時,我們其實在做兩件事 — 計算用戶驗證的狀態(tài)和分發(fā)vuex store
里面的退出事件。在退出之后,我們利用 this.$router.push('/login')
,切換用戶到 login頁面。當(dāng)然你可以改變?nèi)魏文阆胱層脩籼D(zhuǎn)的地方。
就是這樣了。讓我們用vuex構(gòu)建權(quán)限模塊。
Vuex權(quán)限模塊
如果你讀過以前的Setup Node.js Server **部分, 你應(yīng)該注意到我們需要在本地存儲用戶權(quán)限token,同時,當(dāng)用戶被授予權(quán)限后,我們隨時需要重新得到token以及用戶信息。
首先, 讓我們給vuex創(chuàng)建 store.js文件:
import Vue from 'vue' import Vuex from 'vuex' import axios from 'axios' Vue.use(Vuex) export default new Vuex.Store({ state: { status: '', token: localStorage.getItem('token') || '', user : {} }, mutations: { }, actions: { }, getters : { } })
如果你注意到,我們同時引入了vue,vuex和axios,之后讓vue使用vuex,這是因為它是很重要的一步。
我們已經(jīng)定義了state的屬性?,F(xiàn)在vuex的state能夠支持驗證狀態(tài), jwt token以及用戶信息。
創(chuàng)建Vuex登錄事件
Vuex actions
里面主要是提交更改到vuex的store里面。我們將創(chuàng)建一個login 的action,它將使用服務(wù)器對用戶進行身份驗證,并向vuex存儲提交用戶憑據(jù)。打開./src/store.js文件,并添加下面到actions對象中:
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) }) }) },
登錄action通過vuex commit
驗證,我們將用它進行觸發(fā)更改。vuex store里面能記錄這些更改的變化。
我們正在調(diào)用服務(wù)器的登錄路徑并返回必要的數(shù)據(jù)。我們在本地存儲token,之后通過auth_success來更新存儲用戶信息和token。在這一點上,我們也在頭部設(shè)置了axios 。
我們可以在vuex store中存儲token,但是如果用戶離開我們的應(yīng)用,所有在vuex里面的存儲都將消失。為了確保用戶在有效時間內(nèi)不用再重復(fù)登錄,我們只能將token進行本地存儲。
重要的是你知道這些是如何工作的,這樣你就能決定你到底想要實現(xiàn)什么。
我們返回一個promise,這樣我們能在用戶登錄完成后,做出響應(yīng)。
創(chuàng)建Vuex注冊事件
像 login 事件, the register 事件是同一種工作方式。在相同的文件中,添加下面的到actions對象里面:
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.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', err) localStorage.removeItem('token') reject(err) }) }) },
它與login 事件工作方式很像,。稱之為有共同的mutators的 login 和register ,具有相同的目標(biāo)——讓用戶進入系統(tǒng)。
創(chuàng)建Vuex退出事件
我們希望用戶能夠退出系統(tǒng),同時,我們希望銷毀上一次驗證的會話數(shù)據(jù)。在同一個actions對象中,添加下面:
logout({commit}){ return new Promise((resolve, reject) => { commit('logout') localStorage.removeItem('token') delete axios.defaults.headers.common['Authorization'] resolve() }) }
現(xiàn)在,當(dāng)用戶點擊退出時,我們將移除之前在 axios頭部設(shè)置的jwt token 。他們現(xiàn)在將無法執(zhí)行需要token的事務(wù)。
創(chuàng)建Mutations
像我之前提到的,mutators是被用來改變vuex store的狀態(tài)。讓我們在應(yīng)用中給用過的mutators定義。在mutators對象中,添加下面的:
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 = '' }, },
創(chuàng)建Getters
我們使用getter來獲取vuex狀態(tài)中的屬性值。在這種情況下,getter的作用是將應(yīng)用程序數(shù)據(jù)與應(yīng)用程序邏輯分離,并確保我們不會泄露敏感信息。
添加下面的到getters 對象中:
getters : { isLoggedIn: state => !!state.token, authStatus: state => state.status, }
你會同意我的觀點,這是一種更簡潔的訪問存儲數(shù)據(jù)的方式☺️.
在Auth后面隱藏頁面
這篇文章的整個目的是實現(xiàn)身份驗證,讓沒有權(quán)限的用戶看不到某些頁面。為了實現(xiàn)這個,我們需要知道用戶想要訪問的頁面,以及當(dāng)用戶被授權(quán)時,我們有一定的方法來檢驗它。我們同時需要一定的方式,如果某些頁面,授權(quán)或者未授權(quán)的用戶可以單獨或者同時訪問的。這些都是很重要的考慮條件,幸運地是,我們可以通過vue-router來說實現(xiàn)。
定義路由給授權(quán)和未授權(quán)的頁面
打開 ./src/router.js 文件,并引入我們需要的這些:
import Vue from 'vue' import Router from 'vue-router' import store from './store.js' import Home from './views/Home.vue' import 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)
正如你看到的這樣,我們已經(jīng)引入vue,vue-router和我們創(chuàng)建的vuex。我們同時還引入了定義的所有組件,并設(shè)置vue中使用路由。
讓我們定義路由:
[...] 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
我們路由的定義是很普遍的。對于需要權(quán)限驗證的路由,我們需要增加額外的數(shù)據(jù),確保當(dāng)用戶訪問它時,我們可以識別它。這是添加到路由定義中的元屬性的本質(zhì)。如果你想問_”我可以添加更過的數(shù)據(jù)給元數(shù)據(jù)并使用它嗎?”,我很堅定的告訴你,這是絕對的😁。
解決未授權(quán)訪問示例
我們有自己的路由定義。現(xiàn)在,讓我們檢驗未授權(quán)訪問并采取行動。在 router.js文件中,添加下面的在 export default router之前:
router.beforeEach((to, from, next) => { if(to.matched.some(record => record.meta.requiresAuth)) { if (store.getters.isLoggedIn) { next() return } next('/login') } else { next() } })
從這篇文章,通過使用vue router來進行身份驗證,你可以回想一下我們這里有一個非常復(fù)雜的機制,它變得非常大,變得非?;靵y。vuex已經(jīng)幫我們簡化了它,我們可以繼續(xù)給路由添加任何條件。在我們的vuex存儲中,我們可以定義操作來檢查這些條件并獲取返回它們的值。
解決Token過期示例
因為我們在本地存儲token,它可以一直保留著。這意味著無論何時,我們打開自己的應(yīng)用,它可以自動的驗證用戶,即使token已經(jīng)過期失效。最多的情況是,我們的請求會因為無效token而持續(xù)失敗。這對于用戶是個不好的體驗。
現(xiàn)在, 打開./src/App.vue 文件并在script里面,添加下面的:
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) { this.$store.dispatch(logout) } throw err; }); }); } }
我們截獲axios請求,已確定是否獲取到401未授權(quán)響應(yīng)。如果這么做,我們分發(fā) logout 事件,那么用戶獲得退出應(yīng)用。這會讓用戶跳轉(zhuǎn)到之前設(shè)計的 login頁面,這樣他們可以再次登錄。
我贊同這樣會提升用戶體驗 ☺️.
結(jié)束
從以前的文章來看,您可以看到,基于vuex的引入,我們目前的應(yīng)用程序發(fā)生了重大變化。現(xiàn)在,我們不依賴于一直檢查token,不管到哪里都有混亂的條件。我們可以簡單地使用vuex存儲來管理權(quán)限,并且只需使用幾行代碼檢查應(yīng)用程序中的狀態(tài)。
以上所述是小編給大家介紹的使用Vuex解決Vue中的身份驗證問題,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對創(chuàng)新互聯(lián)網(wǎng)站的支持!
網(wǎng)站標(biāo)題:使用Vuex解決Vue中的身份驗證問題
網(wǎng)站鏈接:http://aaarwkj.com/article12/gpjhdc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器、Google、品牌網(wǎng)站制作、網(wǎng)站策劃、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)