1. 程式人生 > 程式設計 >nuxt.js 在middleware(中介軟體)中實現路由鑑權操作

nuxt.js 在middleware(中介軟體)中實現路由鑑權操作

路由鑑權: 就是判斷這個路由當前瀏覽者是否需要許可權訪問。

一般我是通過判斷cookie中儲存的token來判斷的。

在middleware資料夾下新建“auth.js”的檔案

在當前auth.js檔案內判斷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;

 // 在服務端
 if (isServer) {
  // 獲取服務端cookie
  let cookies = getCookie.getcookiesInServer(req)
  // 獲取當前服務端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 {
 //獲取服務端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) : ''
 }
}

在需要路由鑑權的page頁面中使用

比如在 ~/page/index.vue中使用

<script>
  export default {
   name: 'index',// auth 為剛才在在middleware資料夾下新建的auth.js檔案
    middleware: 'auth',}
</script>

js-cookie 擴充套件

1.安裝js-cookie

npm install js-cookie --save

2.使用

1 引用

import Cookie from 'js-cookie'

2 客戶端使用

// 1.獲取
Cookie.get(key)
// 2.設定
Cookie.set('name',value,{expires: 過期時間})
// 3.刪除
Cookie.remove("name")
// 過期時間設定:
let seconds = 3600;   // 過期時間 /秒
let expires = new Date(new Date() * 1 + seconds * 1000);

補充知識:js 中介軟體的簡單實現原理

1.基礎版

我將複雜版的改變了下,該變成不同的方法名,不同的呼叫方法,但是隻要next設定好,比較適合新手檢視

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)
      }*/
      previousFn.call(this,() =>{
        // console.log("use: "+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.首先,在這裡是使用了函數語言程式設計,讓函式賦值給變數.

2.巧妙利用了js class 和原型的this原理(當繼承的函式被呼叫時,this 指向的是當前繼承的物件,而不是繼承的函式所在的原型物件。)

原理剖析

1.為什麼可以形成連結

1.利用了工具2,原型的this,達成連結串列的原理.

nuxt.js 在middleware(中介軟體)中實現路由鑑權操作

當第一個use 呼叫的時候,他的previous 就是最原始的this.middleware

同時,將class 的this.middleware 改成自己的.

當第二個呼叫的時候,他的preious 就是第一個的this.middleware

同理,n個一樣的設定

當最後一個呼叫完畢,此時的this.middleware指向的是最後一個設定的.

2.如何觸發

它使用了run的方法,看起來真的像java的執行緒模組

nuxt.js 在middleware(中介軟體)中實現路由鑑權操作

啟動的是最後一個繫結的this.middleware,如我前面所講.

所以你會看到,當你點選的時候,它立刻出發到了fetch()方法,

3.如何觸發到最開始

按我前面的講法,應該是先觸發最後一個,為什麼他會觸發第一個,是的,當我使用複雜版的時候,我也是很懵逼,搞不懂.然後就有了一開始,我將她變成多個不同的方法,對這些方法依次呼叫.這樣總算扒開了它的三次鏈調,

更應該稱之為遞迴,如果你在next() 方法之後,相應的填寫一些的方法,它一樣會執行.就像遞迴一樣.但他又有連結串列的特性.真的神奇.

nuxt.js 在middleware(中介軟體)中實現路由鑑權操作

這就是他的鏈式呼叫利用,我前面講的兩點.

這樣他返回到了第一次.

4.開始依次觸發相應的,達成中介軟體的一次呼叫

nuxt.js 在middleware(中介軟體)中實現路由鑑權操作

他開始呼叫

呼叫完成後返回到return

nuxt.js 在middleware(中介軟體)中實現路由鑑權操作

然後按照一開始來的路程原路返回.

2.進階版,如何節省程式碼,才是我們的中級目標

js一些黑魔法,才是真正有意思的,

尤其在除錯的時候,如果不熟悉,你就會以為他只運轉了以次,其實,他已經運轉了很多次了.

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)
})

寫法還是一樣,就是它這裡有些很多疑惑的問題.主要就是呼叫函式套兩層的問題

外面套了兩層,當使用call的時候,使用函數語言程式設計,他就無法讀取的到最內層所帶的next()方法,

他這裡使用了setimeout,因為程式立刻執行完畢,它沒有next(),或者next沒有執行到,他就是會立刻返回了.

但是計時器一到就立刻呼叫了.這就是原因.也是一些疑惑的問題

以上這篇nuxt.js 在middleware(中介軟體)中實現路由鑑權操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。