學(xué)習(xí)后臺管理系統(tǒng)

學(xué)習(xí)總結(jié)vue后臺管理系統(tǒng)

后臺頁面的權(quán)限驗證安全性是非常重要的,可以說是一個后臺項目一開始就必須考慮和搭建的基礎(chǔ)核心功能

我們前端所要做的是:? ?不同的權(quán)限對應(yīng)著不同的路由,同時側(cè)邊欄也需要根據(jù)不同的權(quán)限 ,? 異步生成.

技術(shù)棧主要有: vue,vue-router,vuex,axios,vue-cli 3.x(沒有webpack.config.js配置文件,取而代之的是vue.config.js文件), fiddle.php,nodejs(express框架配合myspl搭建過一個簡單的后臺系統(tǒng)框架,cookie.session配合使用,驗證登錄狀態(tài),但是我們這個項目使用的是token來驗證)

一. 登入界面

1.? 登錄: 當(dāng)用戶填寫完賬號和密碼后向服務(wù)端驗證是否正確, 服務(wù)端返回一個token,? 拿到token之后(我會將這個token存儲到cookie中,保證刷新頁面后能記住用戶登錄), 前端會根據(jù)token在去拉取一個user_info的接口來獲取用戶的詳細信息(如用戶權(quán)限,用戶名等等信息)

2.??權(quán)限驗證:? 通過token獲取用戶對應(yīng)的role,? 動態(tài)根據(jù)用戶的role算出其對應(yīng)有權(quán)限的路由, 通過router.addRoutes動態(tài)掛載這些路由.

這些都是通過VUEX全局管理控制的(補充說明: 刷新頁面后vuex的內(nèi)容也會丟失)

具體實施:?

????????首先做一個靜態(tài)登入頁面,兩個input的框, 一個登錄賬號,一個登錄密碼,在放置一個登錄按鈕,綁定click事件,點擊登錄之后向服務(wù)端提交賬號和密碼進行驗證,在向服務(wù)端提交賬號和密碼之前我們前端還可以進行一次簡單的校驗,減輕服務(wù)器壓力,優(yōu)化前端代碼

? ? ? ? click綁定登錄按鈕,當(dāng)點擊按鈕,提交賬號密碼,登錄成功之后在這里推薦是用第三方登錄平臺不重定向到首頁, this.showDialog = true //彈出選擇第三方平臺的dialog,利用this.$store.dispatch提交username信息到vuex中的異步action,并將token儲存在cookie之中,這樣下次打開頁面的時候能記住用戶的登錄狀態(tài),不用在登錄頁面重新登錄了.

注意: 為了安全性,我司在后臺所有token有效期都是seeion,就是瀏覽器關(guān)閉了就丟失了,重新打開瀏覽器都需要重新登錄一次,確保用戶不會因為電腦遺失或者其他原因被人隨意使用賬號

1.1. 獲取用戶信息

用戶登錄成功之后,我們在全局鉤子`router.beforeEach`中攔截路由,判斷是否已獲得token,在獲取token之后我們就要去獲取用戶的基本信息了

(同時要注意一點的是: 我們之后存儲一個用戶token,并沒有存儲別的用戶信息{用戶名,用戶頭像等})

(假設(shè)我把用戶權(quán)限和用戶名存在本地,如果我在這時候有另一臺電腦登錄并修改了自己的用戶名,那再用之前的電腦登錄,,那么他會默認(rèn)去讀取本地cookie中的名字,并不會去拉取新的用戶信息)

所以現(xiàn)在的策略:

頁面會從cookie中查看是否存在token,沒有,就走一遍上部分的流程重新登錄,如果有token,就會把這個token返給后端去拉取user_info,保證用戶信息是最新的.(如果做了單點登錄功能的話, 用戶信息存儲在本地也是可以得,當(dāng)你一臺電腦登錄時谣殊,另一臺會被提下線楚殿,所以總會重新登錄獲取最新的內(nèi)容)

而且從代碼層面我建議還是把?login和get_user_info兩件事分開比較好,在這個后端全面微服務(wù)的年代,后端同學(xué)也想寫優(yōu)雅的代碼~

二. 權(quán)限篇

在工作中,前端會有一個路由表,他表示了每一個路由可訪問的權(quán)限.

1. 用戶登錄之后,通過token獲取用戶的role

2. 動態(tài)根據(jù)用戶的role 算出其對應(yīng)應(yīng)有權(quán)限的路由

3. 再通過router.addRouetes 動態(tài)掛載路由(這些都只是路由級的,后端的權(quán)限是逃不掉的)

????????現(xiàn)在,就是前端來控制頁面級的權(quán)限,不同權(quán)限的用戶顯示不同的側(cè)邊欄和限制其所能進入的頁面(還有少許的按鈕級別的權(quán)限控制),后端會驗證每一個涉及請求的操作,驗證其是否有該操作的權(quán)限,每一個后臺的請求不管是get還是post都會讓前端在請求header里面攜帶用戶token , 后端會根據(jù)改token來驗證在token是否有權(quán)限執(zhí)行該操作,如果沒有權(quán)限就會拋出一個對應(yīng)的狀態(tài)碼,前端測到狀態(tài)碼,做出相應(yīng)的操作

三. 具體實現(xiàn)

1. 創(chuàng)建vue實例的時候?qū)ue-router掛載 , 但這個時候vue-router掛載一些登錄或者不用權(quán)限的公用的頁面

2. 當(dāng)用戶登錄后, 獲取用role, 將role和路由表每個頁面需要的權(quán)限作比較,? 生成最終用戶可訪問的路由表

3. 調(diào)用router.addRoutes(store.getters.addRouters)添加用戶可訪問的路由

4. 使用vuex管理路由表,? 根據(jù)vuex中可訪問的路由渲染側(cè)邊欄組件

router.js中書寫實現(xiàn)路由表:

1. 首先我們要實現(xiàn)如首頁和登錄頁和一些不用權(quán)限的公用頁面vue-router如登錄頁和首頁

2. 之后實例化vue的時候只掛載上面不用權(quán)限的路由export default new Router({routers: 上面的路由})

3. 異步掛載路由:? ?動態(tài)需要根據(jù)權(quán)限加載路由表,在這里我們根據(jù)vue-router官方推薦的方法meta路線元字段(可以`meta`在定義路徑時包含字段,寫在你children里面)標(biāo)簽來標(biāo)示頁面訪問的權(quán)限有哪些 `meta: {role: ['admin' , 'super_editor']}` 表示該頁面只有admin個超級編輯才能有資格進入

注意事項:? 這里有一個需要非常注意的地方就是404 頁面一定要最后加載 , 如果放在constantRouterMap 一同聲明了 404 , 后面的所有頁面都會攔截404

main.js數(shù)據(jù)入口文檔(關(guān)鍵的main.js)

在main.js中主要用的是router.beforeEach(to,from,next) => { if (store.getters.token) {if (to.path === '/login') {next ({path: '/'}))}}}也就是登錄之后,判斷是否有token,如果沒有,那就在免登錄白名單中查找,如果有就是直接進入,如果沒有那么就跳轉(zhuǎn)到登錄頁

????????如果有,并且入口路徑to是從/login登錄頁中進入的,那么就redirect重定向跳轉(zhuǎn)到首頁,

????????否則先判斷當(dāng)前用戶是否已拉取完user_info信息? if(store.getters.roles.length === 0) , 如果是,那么user_info 拉取info`store.dispatch('GetInfo方法名').then`在從這個異步操作中獲取所有的值,const roles = res.data.role,生成可訪問的路由表store.dispatch('GenerateRoutes', {roles}),在獲取到可訪問的路由表后,我們在動態(tài)添加可訪問的路由表router.addRoutes(store.getters.addRouters)? ,在通過next({ ...to , replace: true})hack方法 確保addRouters 已完成 , set the replace: true

如果沒有拉取到info信息就返回err .catch(err => {console.log(err)})

如果當(dāng)有用戶權(quán)限的時候,說明所有可訪問路由已生成 , 如果沒權(quán)限的頁面會自動進入404頁面

如果頁面沒有token時,如果在面登入的白名單中,就直接進入if(whiteList.indexOf(to.path) !== -1){next()} , 否則全部重定向到登入頁面

下面是store/permission.js

這里就是干一件是,通過用戶權(quán)限和之前在router.js里面asyncRouterMap的每一個頁面所需要的權(quán)限做匹配 , 最后放回一個該用戶能夠訪問路由有哪些

這是一個vuex狀態(tài)管理模式,vuex的狀態(tài)管理是響應(yīng)式式的,當(dāng)vue組件從store好讀取狀態(tài)的時候,若store中的狀態(tài)發(fā)生改變 , 那么相應(yīng)的組件也會發(fā)生改變

但是,你不能直接改變store中的狀態(tài).改變store中的狀態(tài)唯一的途徑就是,顯示的提交(commit ) mutation . 在vue組件中獲取vuex狀態(tài)

封裝hasPermission函數(shù),判斷進入頁面是否需要權(quán)限,還有封裝vuex中mobule模塊

側(cè)邊欄

基于element-ui的NavMenu側(cè)邊欄來實現(xiàn)的

遍歷之前算出來的permission_routers , 通過vuex拿到之后動態(tài)v-for渲染(這里因為一些業(yè)務(wù)需要要加很多判斷,比如我們定義路由的時候會加很多參數(shù))

hidden:true? 是否顯示,默認(rèn)為flase? ?

redirect: noredirect如果重定向為conredirect那么重定向不會再面包屑中顯示?

name: 'router-name'? ?名稱由<keep-alive>(必須設(shè)置!!)使用

meta: {role? title? ?icon? ?noCache}??

role: ['admin' , 'editor']??將控制頁面角色(您可以設(shè)置多個角色)

title: 'title'? ?子菜單和面包屑中顯示的名稱(推薦集)

icon: 'svg-name'? 側(cè)邊欄中顯示的圖標(biāo)

noCache: true??如果fasle,頁面將不會被緩存(默認(rèn)為false)

側(cè)邊欄高亮問題: element-ui官方給了default-active

:default-active="$route.path" 將default-active一直指向當(dāng)前路由就可以了,就是這么簡單??

按鈕級別權(quán)限控制

現(xiàn)在是通過獲取到用戶的role之后,在前端用v-if手動判斷來區(qū)分不同權(quán)限對應(yīng)的按鈕的。

理由前面也說了混萝,我司顆粒度的權(quán)限判斷是交給后端來做的,每個操作后端都會進行權(quán)限判斷萍恕。而且我覺得其實前端真正需要按鈕級別判斷的地方不是很多逸嘀,如果一個頁面有很多種不同權(quán)限的按鈕,我覺得更多的應(yīng)該是考慮產(chǎn)品層面是否設(shè)計合理允粤。

axios攔截器

首先我們通過request攔截器在每個請求頭里面塞入token崭倘,好讓后端對請求進行權(quán)限驗證。并創(chuàng)建一個resques攔截器类垫,當(dāng)服務(wù)端返回特殊的狀態(tài)碼司光,我們統(tǒng)一做處理,如沒權(quán)限或者token失效等操作悉患。

兩步驗證

考慮到安全性,簡簡單單一個賬號+密碼的方式很難保證安裝性,推薦借助騰訊的微信或qq作為第三方綁定

賬號和密碼驗證成功之后還需要綁定一個第三方平臺驗證,只需要在原有登錄的邏輯上改造一下就好,登錄成功之后,不直接跳到首頁而是讓用戶兩步登錄,選擇登錄平臺,第三方平臺登錄一樣要通過OAuth2.0授權(quán)

如微信還必須是你授權(quán)賬號的一級域名残家。所以你授權(quán)的域名是vue-element-admin.com,你就必須重定向到vue-element-admin.com/xxx/下面,所以你需要寫一個重定向的服務(wù)售躁,如vue-element-admin.com/auth/redirect?a.com 跳到該頁面時會再次重定向給a.com坞淮。

所以我們后臺也需要開一個authredirect頁面:代碼茴晋。他的作用是第三方登錄成功之后會默認(rèn)跳到授權(quán)的頁面,授權(quán)的頁面會再次重定向回我們的后臺回窘,由于是spa诺擅,改變路由的體驗不好,我們通過window.opener.location.href的方式改變hash毫玖,在login.js里面再監(jiān)聽hash的變化。當(dāng)hash變化時凌盯,獲取之前第三方登錄成功返回的code與第一步賬號密碼登錄之后返回的uid一同發(fā)送給服務(wù)端驗證是否正確付枫,如果正確,這時候就是真正的登錄成功驰怎。

外賣后臺管理系統(tǒng)

后臺界面的首頁:

是由element的? 時間區(qū)間插件 , 省市區(qū)級聯(lián)插件,? 樹形插件選擇不同的角色;這幾個條件, 來篩選對應(yīng)條件的數(shù)據(jù)

????????我們把后臺返回的數(shù)據(jù)放到Echarts的折線圖,餅狀圖里面,每次登錄系統(tǒng)每個角色看到的這個統(tǒng)計數(shù)據(jù)是不一的,這取決于我們前端利用token拉取的user_info接口中所獲取的信息,參數(shù)是不一樣的 ,?這樣做到了有公司管理者對公司整體的運營情況的一個把握

? ? ? ? 我們的有一些系統(tǒng)會給入駐的商家時候,他們可以添加商店 , 我們審核 ,給予相應(yīng)的權(quán)限,我們前端在通過token獲取roel,根據(jù)用戶的roel動態(tài)算出其擁有權(quán)限的路由,之后通過router.addRouters動態(tài)掛載這些路由

? ? ? ? 商戶可以上傳一些菜品 , 圖片 , 價格等參數(shù) , 我們后臺人員會檢測到每個商家的經(jīng)營情況 , 動態(tài)的給他們推送一些活動 , 首頁置頂之類的;

? ? ? ? 這里我們使用了 element的Upload上傳插件;? Transfer 穿梭框插件,? Form插件,? Table表格插件,? Pagination 分頁插件

? ? ? ? 在利用flex布局,布局: 頭部固定,左邊固定,右邊自適應(yīng)? display: flex;??

flex布局中分為主軸方向和交叉軸:
主軸方向: 我們在彈性容器上通過flex-direction修改主軸方向;如果主軸方向改變那么交叉軸也會變它有幾個屬性,分為row左->右 , column上->下 , row-reverse左<-右 , column-reverse上<-下

彈性布局永遠沿著主軸排列,當(dāng)主軸排列不下,我們可以通過flex-wrap進行換行 , nowrap,不換行 一行顯示 , wrap換行下一行顯示 , wrap-reverse 反向換行

復(fù)合屬性: flex-flow = flex-drection + flex-wrap

復(fù)合屬性flex = flex-grow + flex-shrink + flex-basis? ??

flex-grow: 放大比例? ? ? flex-shrink生效前的尺寸? ? ? ? ?flex-basis設(shè)置的是元素在主軸上的初始尺寸

主軸上元素的對齊方式: justify-content: flex-start默認(rèn)左->右 , flex-end左<-右 , center居中 ,? ?space-between左右對齊中間自適應(yīng) , space-around平分剩余空間

交叉軸上的對齊方式: align-items

stretch: 默認(rèn)值,會在交叉軸方向撐滿? ? ? ? flex-start沿前端? ? ? ? flex-end沿交叉軸終點對齊? ? ? ? center沿交叉軸中點對齊? ? ? ? baseline沿第一行文字的基線對齊...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阐滩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子县忌,更是在濱河造成了極大的恐慌掂榔,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件症杏,死亡現(xiàn)場離奇詭異装获,居然都是意外死亡,警方通過查閱死者的電腦和手機厉颤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門穴豫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人逼友,你說我怎么就攤上這事精肃。” “怎么了帜乞?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵司抱,是天一觀的道長。 經(jīng)常有香客問我黎烈,道長习柠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任照棋,我火速辦了婚禮津畸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘必怜。我一直安慰自己肉拓,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布梳庆。 她就那樣靜靜地躺著暖途,像睡著了一般卑惜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上驻售,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天露久,我揣著相機與錄音,去河邊找鬼欺栗。 笑死毫痕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的迟几。 我是一名探鬼主播消请,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼类腮!你這毒婦竟也來了臊泰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蚜枢,失蹤者是張志新(化名)和其女友劉穎缸逃,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體厂抽,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡需频,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了筷凤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贺辰。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嵌施,靈堂內(nèi)的尸體忽然破棺而出饲化,到底是詐尸還是另有隱情,我是刑警寧澤吗伤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布吃靠,位于F島的核電站,受9級特大地震影響足淆,放射性物質(zhì)發(fā)生泄漏巢块。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一巧号、第九天 我趴在偏房一處隱蔽的房頂上張望族奢。 院中可真熱鬧,春花似錦丹鸿、人聲如沸越走。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽廊敌。三九已至铜跑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間骡澈,已是汗流浹背锅纺。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留肋殴,地道東北人囤锉。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像护锤,于是被迫代替她去往敵國和親官地。 傳聞我的和親對象是個殘疾皇子晨雳,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353