當前位置:編程學習大全網 - 源碼下載 - Vue項目前後端分離下的前端認證方案

Vue項目前後端分離下的前端認證方案

#?Vue項目前後端分離下的前端認證方案

###?技術棧

前端Vue家族桶,背景。網。

###?需求分析

1.?前端路由認證,屏蔽地址欄入侵

2.?路由數據由後臺管理,前端只是按照固定的規則異步加載路由。

3.?權限控制精確到每個按鈕。

4.?自動更新令牌

5.?同壹瀏覽器只能登錄壹個帳戶。

###?前端方案

& gt?對於需求1,2,3,采用異步加載路由方案。

1.?首先,編寫vue全局路由保護。

2.?排除登錄路由和未經驗證的路由。

3.?登錄後請求提取用戶菜單數據。

4.?在vuex中處理菜單和路線匹配數據

5.?通過addRoutes '將vuex中處理過的路由數據異步推送到路由中。

```

router.beforeEach((to,?從,?下壹個)?= & gt?{

//?判斷當前用戶是否拉取了權限菜單。

如果?(store . state . sidebar . user router . length?===?0)?{

//?沒有菜單時拉動

getMenuRouter()

。然後(res?= & gt?{

讓?_菜單?=?res.data.Data.ColumnDataList?||?[];

//?如果?(RES . data . data . column datalist . length?& gt?0)?{

//?整理好菜單&;路由數據

store.commit("setMenuRouter ",_ menu);

//?推送許可傳送列表

router . add routes(store . state . sidebar . user router);

下壹個({...到,?替換:?真的嗎?});

//?}

})

。catch(呃?= & gt?{

//?console . log(err);

//?Message.error("服務器連接失敗");

});

}?不然呢?{

//當有用戶權限時,所有可訪問的路由都已生成?如果妳未經許可進入菜單,妳將自動進入404頁。

如果?(to.path?==?"/login ")?{

下壹個({

姓名:?"索引"

});

}?不然呢?{

next();

}

}

}?不然呢?{

//?沒有登錄狀態時重定向到登錄?或者可以進入免登錄狀態的路徑

如果?(to.path?==?"/登錄"?||?to.meta.auth?===?0)?{

next();

}?不然呢?{

下壹個({

路徑:?"/登錄"

});

}

}

});

```

#####?註意

& gt?我這裏的無認證路由直接寫在router文件夾下的index.js中,通過路由元信息meta攜帶指定的標識符。

```

{

路徑:?"/err-404 ",

姓名:?“錯誤404”,

meta:?{

?認證:?錯誤的

},

組件:?化解?= & gt?要求(["../views/error/404.vue"],?解決)

},

```

& gt?上面提到的路由都是根據後臺返回的菜單數據,按照壹定的規則生成的,所以有些不是菜單,需要登錄狀態的路由都寫在router文件夾下的router.js中。在處理上述步驟4中後臺返回的菜單數據時,通過addRoutes '將它們與處理後的菜單路由數據壹起推送到壹起。?

這樣做會有壹定的被地址欄入侵的風險,但是這裏的路由大多不是很重要。如果想咳咳,可以設置字典配合後臺接口,精準加載每條路線。

```

//?加入企業

{

路徑:?"/加入-公司",

姓名:?“加入公司”,

組件:?化解?= & gt?要求([`@/views/index/join-company . vue `],?解決)?

},

```

& gt?在vuex中,分配的菜單數據被轉換成前端可用的路由數據。我是這樣做的:

添加菜單時,管理系統需要填寫頁面地址字段“Url”。前端獲取後臺菜單數據後,根據‘Url’字段匹配路由加載的文件路徑。每個菜單壹個文件夾的好處是可以在這裏拆分這個菜單的js,css和private組件。

```

menu.forEach(項目?= & gt?{

讓?routerItem?=?{

路徑:?項目。Url,

姓名:?項目。Id,

meta:?{

auth:?項目。孩子們,

},?//?路由元信息?定義路線時可以攜帶的參數可以用來管理每條路線的按鈕操作權限。

組件:?化解?= & gt

要求([`@/views${item。Url}/index.vue`],?解決)?//?路線圖實景路徑

};

router box . push(route item);

});

```

& gt?我這樣做是關於如何準確控制每個按鈕。我把按鈕代碼放在路由元信息中,匹配到當前路由下,控制頁面上的按鈕是否創建。

菜單數據返回多級結構,每個菜單下的子集是當前菜單下的按鈕權限碼數組。我把每個菜單下的按鈕放在這個菜單的路由元信息meta.auth中。這樣做的好處是,按鈕權限檢查只需要匹配每個菜單路由元信息下的數據,所以檢查池長度通常不超過5。

```

已創建()?{

這是主人嗎?=?這個。$route.meta.auth.map(item?= & gt?項目。碼);

}

方法:?{

匹配所有者(auth)?{

回歸?this.owner.some(item?= & gt?物品?===?auth);

}

}

```

& gt?Demand 4自動更新令牌,這是壹個簡單的時間判斷,在請求頭中增加壹個字段,通知後臺更新令牌,並在頭返回。當前端接收到帶有令牌的請求時,它直接更新令牌。

```

//?在axios的請求攔截器中

讓?token?=?getSession(auth _ code);

如果?(token)?config.headers.auth?=?token

如果?(tokenIsExpire(token))?{

//?判斷jwt是否需要刷新。

config.headers.refreshtoken?=?真實;

}

//?在axios的響應攔截器中。

如果?(res.headers.auth)?{

setSession(auth_code,RES . headers . auth);

}

```

& gt?處理需求5很麻煩。妳只能用' cookie '或者' local '穿越標簽頁,所以我這裏不允許用' cookie ',所以采用了' localstorage '。通過打開的新頁面讀取' localstorage '中的' token '數據,同步多個頁面的賬戶信息。“token”使用的“jwt”在前端通過md5加密。

這裏需要註意的壹點是,切換頁面時要立即同步賬號信息。

& gt?需求5改造後,全局路由守護是這樣的:

```

功能?_AUTH_()?{

//?切換窗口時檢查賬號是否有變化。

window . addevent listener(" visibility change ",函數()?{

讓?Local_auth?=?getLocal(auth_code,真);

讓?Session_auth?=?getSession(auth _ code);

如果?(document.hidden?==?假的?& amp& amp?Local_auth?& amp& amp?Local_auth?!=?Session_auth)?{

setSession(auth_code,Local_auth,?真);

router.go(0)

}

})

router.beforeEach((to,?從,?下壹個)?= & gt?{

//?判斷當前用戶是否拉取了權限菜單。

如果?(store . state . sidebar . user router . length?===?0)?{

//?沒有菜單時拉動

getMenuRouter()

。然後(res?= & gt?{

讓?_菜單?=?res.data.Data.ColumnDataList?||?[];

//?如果?(RES . data . data . column datalist . length?& gt?0)?{

//?整理好菜單&;路由數據

store.commit("setMenuRouter ",_ menu);

//?推送許可傳送列表

router . add routes(store . state . sidebar . user router);

下壹個({...到,?替換:?真的嗎?});

//?}

})

。catch(呃?= & gt?{

//?console . log(err);

//?Message.error("服務器連接失敗");

});

}?不然呢?{

//當有用戶權限時,所有可訪問的路由都已生成?如果妳未經許可進入菜單,妳將自動進入404頁。

如果?(to.path?==?"/login ")?{

下壹個({

姓名:?"索引"

});

}?不然呢?{

next();

}

}

}?不然呢?{

//?沒有登錄狀態時重定向到登錄?或者可以進入免登錄狀態的路徑

如果?(to.path?==?"/登錄"?||?to.meta.auth?===?0)?{

next();

}?不然呢?{

下壹個({

路徑:?"/登錄"

});

}

}

});

}

```

& gt?需求5改造後的axios的請求攔截器是這樣的。因為ie無法使用visibilitychange,嘗試百度其他屬性無效,所以在發送請求前大致處理如下:

```

如果?(ie瀏覽器)?{?

setLocal('_ie ',?Math.random()

讓?Local_auth?=?getLocal(auth_code,真);

讓?Session_auth?=?getSession(auth _ code);

如果?(Local_auth?& amp& amp?Local_auth?!=?Session_auth)?{

setSession(auth_code,Local_auth,?真);

router.go(0)

回歸?錯誤的

}

}

```

& gt?這裏需要註意壹個小問題:由於使用了‘本地’,第壹次打開瀏覽器時,可能會提示登錄已經過期。相信在座的各位都能找到適合自己的解決方案。

# # #結論

經過這些簡單易用的處理,壹個基本符合要求的前端認證方案就誕生了。

  • 上一篇:2022描寫彩虹的唯美句子
  • 下一篇:QQ幹貨之快速批量掛出常用ip
  • copyright 2024編程學習大全網