nuxt.js 在middleware(中間件)中實(shí)現(xiàn)路由鑒權(quán)操作
路由鑒權(quán): 就是判斷這個(gè)路由當(dāng)前瀏覽者是否需要權(quán)限訪問。
一般我是通過判斷cookie中存儲的token來判斷的。
在middleware文件夾下新建“auth.js”的文件
在當(dāng)前auth.js文件內(nèi)判斷cookie中是否包含token字段
import getCookie from '~/utils/getCookie' export default function ({route, req, res, redirect}) { let isClient = process.client; let isServer = process.server; let redirectURL = '/sign'; var token, path; // 在服務(wù)端 if (isServer) { // 獲取服務(wù)端cookie let cookies = getCookie.getcookiesInServer(req) // 獲取當(dāng)前服務(wù)端cookie中是否含有token字段 token = cookies.token ? cookies.token : '' } // 在客戶端 if (isClient) { // 獲取客戶端(本地)cookie中的token字段 token = getCookie.getcookiesInClient('token') } // 判斷是否獲取到token // 未獲取到,重定向到登陸頁面 if (!token) { redirect(redirectURL) } }
新建獲取cookie的文件
~/uitls/getCookie.js
首先:下載js-cookie
npm i js-cookie -s import Cookie from 'js-cookie' export default { //獲取服務(wù)端cookie getcookiesInServer:function (req) { let service_cookie = {}; req && req.headers.cookie && req.headers.cookie.split(';').forEach(function (val) { let parts = val.split('='); service_cookie[parts[0].trim()] = (parts[1] || '').trim(); }); return service_cookie; }, //獲取客戶端cookie getcookiesInClient:function (key) { return Cookie.get(key) ? Cookie.get(key) : '' } }
在需要路由鑒權(quán)的page頁面中使用
比如在 ~/page/index.vue中使用
<script> export default { name: 'index', // auth 為剛才在在middleware文件夾下新建的auth.js文件 middleware: 'auth', } </script>
js-cookie 擴(kuò)展
1.安裝js-cookie
npm install js-cookie --save
2.使用
1 引用
import Cookie from 'js-cookie'
2 客戶端使用
// 1.獲取 Cookie.get(key) // 2.設(shè)置 Cookie.set('name', value, {expires: 過期時(shí)間}) // 3.刪除 Cookie.remove("name") // 過期時(shí)間設(shè)置: let seconds = 3600; // 過期時(shí)間 /秒 let expires = new Date(new Date() * 1 + seconds * 1000);
補(bǔ)充知識:js 中間件的簡單實(shí)現(xiàn)原理
1.基礎(chǔ)版
我將復(fù)雜版的改變了下,該變成不同的方法名,不同的調(diào)用方法,但是只要next設(shè)置好,比較適合新手查看
class Middleware { constructor () { this.middleware = (next)=>{//console.log("this.middleware: "+next) /*this.middleware: () =>{ console.log("use: "+fn.call(this, next)); return fn.call(this, next)*/ return next(); } } run (fn) { // console.log(this) this.middleware( () => fn.call(this,"nihaoafddsf") ) } use (fn) { const previousFn = this.middleware this.middleware=(next)=>{ // console.log(next) /*() =>{ console.log("fetch: "+fn.call(this, next)); return fn.call(this, next) }*/ previousFn.call(this, () =>{ // console.log("use: "+fn.call(this, next)); return fn.call(this, next) }) } } fetch(fn){ const previousFn = this.middleware this.middleware=(next)=>{ // console.log(next)//() => fn.call(this,"nihaoafddsf") previousFn.call(this, () =>{ console.log("fetch: "+fn) return fn.call(this, next) }) } } } let bnm = new Middleware; bnm.use( (next)=>{ console.log(3) console.log(next) next() } ) bnm.fetch((next)=>{ console.log("nihaoa") next() }) bnm.run(function (canshu) { console.log(1) console.log(canshu) })
工具
1.首先,在這里是使用了函數(shù)式編程,讓函數(shù)賦值給變量.
2.巧妙利用了js class 和原型的this原理(當(dāng)繼承的函數(shù)被調(diào)用時(shí),this 指向的是當(dāng)前繼承的對象,而不是繼承的函數(shù)所在的原型對象。)
原理剖析
1.為什么可以形成鏈接
1.利用了工具2,原型的this,達(dá)成鏈表的原理.
當(dāng)?shù)谝粋€(gè)use 調(diào)用的時(shí)候,他的previous 就是最原始的this.middleware
同時(shí),將class 的this.middleware 改成自己的.
當(dāng)?shù)诙€(gè)調(diào)用的時(shí)候,他的preious 就是第一個(gè)的this.middleware
同理,n個(gè)一樣的設(shè)置
當(dāng)最后一個(gè)調(diào)用完畢,此時(shí)的this.middleware指向的是最后一個(gè)設(shè)置的.
2.如何觸發(fā)
它使用了run的方法,看起來真的像java的線程模塊
啟動的是最后一個(gè)綁定的this.middleware,如我前面所講.
所以你會看到,當(dāng)你點(diǎn)擊的時(shí)候,它立刻出發(fā)到了fetch()方法,
3.如何觸發(fā)到最開始
按我前面的講法,應(yīng)該是先觸發(fā)最后一個(gè),為什么他會觸發(fā)第一個(gè),是的,當(dāng)我使用復(fù)雜版的時(shí)候,我也是很懵逼,搞不懂.然后就有了一開始,我將她變成多個(gè)不同的方法,對這些方法依次調(diào)用.這樣總算扒開了它的三次鏈調(diào),
更應(yīng)該稱之為遞歸,如果你在next() 方法之后,相應(yīng)的填寫一些的方法,它一樣會執(zhí)行.就像遞歸一樣.但他又有鏈表的特性.真的神奇.
這就是他的鏈?zhǔn)秸{(diào)用利用,我前面講的兩點(diǎn).
這樣他返回到了第一次.
4.開始依次觸發(fā)相應(yīng)的,達(dá)成中間件的一次調(diào)用
他開始調(diào)用
調(diào)用完成后返回到return
然后按照一開始來的路程原路返回.
2.進(jìn)階版,如何節(jié)省代碼,才是我們的中級目標(biāo)
js一些黑魔法,才是真正有意思的,
尤其在調(diào)試的時(shí)候,如果不熟悉,你就會以為他只運(yùn)轉(zhuǎn)了以次,其實(shí),他已經(jīng)運(yùn)轉(zhuǎn)了很多次了.
class Middleware { constructor () { this.i = 0; this.middleware = (next) => { console.log(next);return next()} } run (fn) { console.log(this) this.middleware( () => fn.call(this) ) } use (fn) { const previousFn = this.middleware this.middleware = (next) => previousFn.call(this, () =>{ console.log(fn); return fn.call(this, next) }) } } const instance = new Middleware() instance.use(function (next) { setTimeout(() => { console.log('first') this.firstMiddlewareLoaded = true next() }, 500) }) instance.use(function (next) { setTimeout(() => { console.log('second') this.secondMiddlewareLoaded = true next() }, 250) }) instance.use(function (next) { console.log('third') this.ThirdMiddlewareLoaded = true next() }) const start = new Date() instance.run(function () { console.log('first middleware loaded:', this.firstMiddlewareLoaded) console.log('second middleware loaded:', this.secondMiddlewareLoaded) console.log('Third middleware loaded:', this.ThirdMiddlewareLoaded) console.log('time passed:', new Date() - start) })
寫法還是一樣,就是它這里有些很多疑惑的問題.主要就是調(diào)用函數(shù)套兩層的問題
外面套了兩層,當(dāng)使用call的時(shí)候,使用函數(shù)式編程,他就無法讀取的到最內(nèi)層所帶的next()方法,
他這里使用了setimeout ,因?yàn)槌绦蛄⒖虉?zhí)行完畢,它沒有next(),或者next沒有執(zhí)行到,他就是會立刻返回了.
但是計(jì)時(shí)器一到就立刻調(diào)用了.這就是原因.也是一些疑惑的問題
以上這篇nuxt.js 在middleware(中間件)中實(shí)現(xiàn)路由鑒權(quán)操作就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue-virtual-scroll-list虛擬組件實(shí)現(xiàn)思路詳解
這篇文章主要給大家介紹了關(guān)于vue-virtual-scroll-list虛擬組件實(shí)現(xiàn)思路的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-02-02Vue 樣式切換及三元判斷樣式關(guān)聯(lián)操作
這篇文章主要介紹了Vue 樣式切換及三元判斷樣式關(guān)聯(lián)操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08Vue.js實(shí)現(xiàn)一個(gè)自定義分頁組件vue-paginaiton
這篇文章主要為大家詳細(xì)介紹了Vue.js實(shí)現(xiàn)一個(gè)自定義分頁組件vue-paginaiton的具體代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09Vue3中Element-Plus分頁(Pagination)組件的使用
Element-Plus分頁(Pagination)組件在開發(fā)過程中數(shù)據(jù)展示會經(jīng)常使用到,同時(shí)分頁功能也會添加到頁面中,下面我們就來學(xué)習(xí)一下它的具體使用,需要的可以參考一下2023-11-11