1. 程式人生 > >Vue + ElementUI 手擼後臺管理網站基本框架(三)登入及導航選單載入

Vue + ElementUI 手擼後臺管理網站基本框架(三)登入及導航選單載入

登入授權

登入及安全

從前端看來,使用者的登入和授權看起來感覺十分簡單,無非就是輸入使用者名稱和密碼,傳給後臺確認登入。但其實這裡面還是有很多需要注意的問題,這裡簡單列舉一下:

  • 所有資料的傳輸過程應當保證安全,保證資料不會在傳輸過程中洩露或劫持
  • 應當有一種機制來校驗請求發起人是否是之前登入的使用者
  • 應當有一種過期機制使使用者不能保持永久登入狀態

以上這些問題實質上都是web開發中需要注意的安全性問題。雖然這些問題大部分由後端人員解決,前端只需要配合完成即可,但如果瞭解這些問題那就更好了。接下來我針對這三個問題逐條簡單分析一下,期間涉及到的相關知識點大家可以自行搜尋,此處不再進行深入說明(否則就變成安全介紹了)。

第一種問題的實質是資料傳輸的安全,防止資訊洩露。針對於這種情況,目前最好的辦法就是使用HTTPS,而不是使用HTTP。

第二種問題實際上是在Web開發中經常遇到的安全問題——跨站請求偽造(CSRF/XSRF)。即攻擊者可以利用漏洞在其他網站上傳送請求偽裝成本站的正常請求,這樣攻擊者可以在使用者完全不知情的情況下進行任何操作。這種問題目前的解決方法就是使用Token機制。當用戶登入後服務端返回一個Token,之後的每次請求都要攜帶這個Token,如果在服務端Token不匹配則意味著授權失敗。

第三種問題實際上就是為了讓使用者不能永久處於登入狀態,否則使用者登入一次就能獲得永久授權。在實際中就是Token本身要具備時效性,要有過期機制。至於過期後是返回登入頁面重新登入亦或是自動續期亦或是自動重新整理,這就是由後端決定的了,前端只要配合好即可。

為了和後端人員配合好,前端必須做出一定的修改,接下來將說明這些的問題的前端解決方案。請注意,這些方法實質上都是對axios的設定。

為每個請求增加Token

在上一章節中,我們其實有提到Token的攜帶方法,即介面許可權控制部分。這裡不在細說,直接上之前的程式碼即可。不過有一點需要注意的是Token也需要同步記錄到Cookie中,否則頁面重新整理後,js內部的變數值將還原成初始狀態。如果記錄到Cookie後,則在頁面重新整理後可以直接從Cookie中取值,再賦給js變數。

const service = axios.create()

// http request 攔截器
// 每次請求都為http頭增加Authorization欄位,其內容為Token
service.interceptors.request.use( config => { config.headers.Authorization = `${Token}` return config } ); export default service

Token超時及重新整理機制

Token超時自動消失的方法可以直接通過設定Cookie的失效時間來確定。這樣,在每次請求發起時,校驗Cookie中是否有Token,如果沒有則需要對Token進行重新整理;如果有則直接請求介面即可。

而Token的重新整理目前總結為兩種方式:

  • 每次請求時判斷Token是否超時,若超時則獲取新Token
  • 每次請求時判斷Token是否超時,若超時則跳轉到授權頁面

這兩種方式在新Token的獲取上實際並沒有太大的區別,無非就是自動呼叫介面及跳到單獨頁面呼叫介面而已。但是如果頁面中當前有多個請求被髮起,那麼則會出現較大的差異。前者需要對所有請求進行延遲處理,保證介面新Token的介面獲取到資料後再執行之前的請求,否則這些請求將因Token超時直接失敗;後者則是需要中斷當前的所有的請求,並立即跳轉到對應頁面。

檢視axios中斷請求方法,在官方文件中搜索cancelToken:axios

// 第一種方式的校驗函式
// 設定getToken鎖,如果當前正在獲取新Token, 則其他請求做延遲處理
var getTokenLock = false

function checkToken(callback){
    // 檢測Token是否過期
    if(!hasToken()){
        // 如果當前有請求正在獲取Token
        if(getTokenLock){
            setTimeout(function(){
                checkToken(callback)
            }, 500)
        } else {
            getTokenLock = true
            getNewToken().then(() => {
                callback()
                getTokenLock = false
            })
        }
    } else {
        // token未過期
        callback()
    }
}

// axios 攔截器
service.interceptors.request.use(
    config => {
        checkToken(function(){
            config.headers.Authorization = `${Token}`
        })
        return config
    }
);
var CancelToken = axios.CancelToken
var cancel

// 第二種方式的校驗函式
function checkToken(callback){
    // 檢測Token是否過期
    if(!hasToken()){
        // 中斷當前請求
        cancel()
        // 跳轉到固定的授權頁面
        router.push('/auth')
    } else {
        // token未過期
        callback()
    }
}

// axios攔截器
service.interceptors.request.use(
    config => {
        config.cancelToken = new CancelToken(function executor(c) {
            cancel = c;
        })
        checkToken(function(){
            config.headers.Authorization = `${Token}`
        })
        return config
    }
);

建立系統選單

在建立選單前,我們需要先確定一下我們選單中具體的細節:當點選選單時,只能有一個子選單保持展開;如果點選一級選單,其他子選單也應該收回。而在element官網的展示中,第二個需求並沒有實現。所以這裡我會逐步說明如何實現這樣的選單。

模擬選單資料

上個章節中,我們已經模擬過一次使用者登入後的返回資料。不過當時只是根據該資料進行許可權判斷,並沒有在UI上生成對應的系統選單。這裡我們再來看一下模擬的選單列表資料

var data = [
    {
        path: '/home',
        name: '首頁'
    },
    {
        name: '系統元件',
        child: [
            {
                name: '介紹',
                path: '/components'
            },
            {
                name: '功能類',
                child: [
                    {
                        path: '/components/permission',
                        name: '詳細鑑權'
                    },
                    {
                        path: '/components/pageTable',
                        name: '表格分頁'
                    }
                ]
            }
        ]
    }
]    

看著這樣的資料,我們要把它生成UI選單,其實質就是遞迴。

生成選單

為了實現我們需要的選單,這裡列舉三個非常重要的屬性:

router模式:啟用導航時以 index 欄位作為 path 進行路由跳轉。
default-active:當前啟用的導航,以index欄位為值。如果元件渲染前有預設值,則渲染後會按照該值來展開的導航。
unique-opened:保證只有一個子選單展開。同樣以index欄位作為索引,如果某些選單的index重複或者沒有則會使該功能失效

想要同時使用者三種模式,則必須保證所有選單節點即el-menu-item都具有index,且index不能重複。所以我們最主要的就是在遞迴過程中生成不同的index:對那些非葉子節點(即選單分組)直接算出index,葉子節點(即實際的展示頁面)則直接將跳轉路徑賦值給index

所以通過遞迴方式得到的選單樹結構應該是這樣的(注意index欄位的不同):

<el-menu>
    <el-menu-item :index="/home">首頁</el-menu-item>
    <el-submenu :index="1">
        <template slot="title">系統元件</template>
        <el-menu-item :index="/components">介紹</el-menu-item>
        <el-submenu :index="1-1">
            <template slot="title">功能類</template>
            <el-menu-item :index="/components/permission">詳細鑑權</el-menu-item>
            <el-menu-item :index="/components/pageTable">表格分頁</el-menu-item>
        </el-submenu>
    </el-submenu>
    ...
</el-menu>

在明確遞迴後應該產生何種結構的樹後,我們就可以開始編寫選單生成的程式碼了。

// nav.vue
// navList為選單列表資料
<template>
    <el-menu router unique-opened  :default-active="onRoutes">
        // 迴圈navList陣列,將每項的值及index傳給nav-item元件
        <nav-item v-for="(item, index) in navList"  :item="item" :navIndex="String(index)" :key="index">
        </nav-item>
    </el-menu>
</template>

export default {
    computed: {
        // 首次進入頁面時展開當前頁面所屬的選單
        onRoutes(){
            return this.$route.path
        }
    }
}
// navItem.vue
<template>
    // 如果當前item中有子節點
    <el-submenu v-if="item.child && item.child.length" :index="navIndex"> 
        <!-- 建立選單分組 -->
        <template slot="title">{{ item.name }}</template>
        <!-- 遞迴呼叫自身,直到subItem不含有子節點 -->
        <nav-item v-for="(subItem,i) in item.child" :key="navIndex+'-'+i" :navIndex="navIndex+'-'+i" :item="subItem" >
        </nav-item>
    </el-submenu>

    // 如果當前item不含有子節點
    <el-menu-item v-else :index="item.path">{{ item.name }}</el-menu-item>
</template>
<script>
    export default {
        // 遞迴元件必須有name
        name: 'navItem',
        props: ['item','navIndex']
    }
</script>

實現點選一級選單收回所有其他子選單

由於我們過於苛刻的要求,element官網中並沒有提供相關的示例,同時也沒有提供任何可以手動關閉選單的方法。所以這裡我們需要通過ref來調取官網文件中未標明,但確存在於<el-menu>元件中的方法。

// nav.vue
<template>
    // 增加ref欄位,直接訪問子元件方法。同時註冊select事件,當選單點選時觸發
    <el-menu router unique-opened ref="navbar" :default-active="onRoutes" @select="selectMenu">
        <nav-item v-for="(item, n) in navList" :item="item" :navIndex="String(n)" :key="n">
    </el-menu>
</template>

export default {
    computed: {
        onRoutes(){
            return this.$route.path
        }
    },
    methods: {
        selectMenu(index, indexPath){
            let openedMenus = this.$refs.navbar.openedMenus
            let openMenuList
            // 如果點選的是二級選單,則獲取其後已經開啟的選單
            if(indexPath.length > 1){
                let parentPath = indexPath[indexPath.length-2]
                openMenuList = openedMenus.slice(openedMenus.indexOf(parentPath)+1)
            } else{
                openMenuList = openedMenus
            }
            openMenu = openMenu.reverse()
            openMenu.forEach((ele) => {
                this.$refs.navbar.closeMenu(ele)
            })
        }
    }
}

NEXT——主題切換

在下一章中將講述如何實現主題切換,同時歡迎大家討論更好的方法,或者解決文章中提出的問題。感激不盡。

原始碼

當前原始碼地址:https://github.com/harsima/vue-backend
請注意,該原始碼會不斷更新(因為工作很忙不能保證定期更新)。原始碼涉及到的東西有超出本篇教程的部分,請酌情閱讀。

本系列目錄

相關推薦

Vue + ElementUI 後臺管理網站基本框架()登入導航選單載入

登入授權 登入及安全 從前端看來,使用者的登入和授權看起來感覺十分簡單,無非就是輸入使用者名稱和密碼,傳給後臺確認登入。但其實這裡面還是有很多需要注意的問題,這裡簡單列舉一下: 所有資料的傳輸過程應當保證安全,保證資料不會在傳輸過程中洩

Vue + ElementUI 後臺管理網站基本框架(二)許可權控制

前端許可權控制的本質 在管理系統中,感覺最讓新手們搞不懂就是許可權管理這部份了,而這也是後臺管理系統中最基礎的部分。 一般說來,許可權管理可以分為兩種情況:第一種為頁面級訪問許可權,第二種為資料級操作許可權。第一種情況是非常常見的,即使用者是否

Vue + ElementUI 後臺管理網站基本框架(一)建立專案

建立工程目錄 在開始一切的講解前,我們先建立一個全新的工程。推薦直接使用vue官方提供的命令列工具vue-cli,它能快速的生成一個基於vue和webpack的單頁面應用。 # 全域性安裝vue-cli npm install vue-cl

Vue + ElementUI 後臺管理網站基本框架(零)前言篇

歡迎轉載,但需標明出處 前言 本教程中涉及的後臺管理系統使用 vue + element + webpack 作為基礎框架,SPA架構,均採用vue的單檔案元件形式進行書寫,故你需要確保PC中擁有nodeJS環境,保證程式碼可以進行後期編譯,

vue】基於vue+elementUI+seajs的後臺管理框架demo,導航選單+tab頁面顯示跳轉

後臺管理外框架demo,由vue + seajs架構的後臺管理框架,頁面主要三部分組成:頭部、左側選單、主介面。左側選單以路由控制在主介面以tab頁形式展示。 seajs主要是用來做程式碼組織的,方便模組化載入。功能上實現主要是vue+elementUI+vuex。 左側導航(自定義app-nav元件) 整

Vue2.0 + ElementUI 寫許可權管理系統後臺模板(四)——元件結尾

i18n國際化多語言翻譯使用 框架採用vue-i18n版本 8.4.0, 使用npm安裝 新建資料夾src/i18n,目錄如下 i18n.js //i18n.js import Vue from 'vue' import locale from 'element-ui/lib/loc

webpack+vue.js+elementUI試做後臺管理頁面

前言 由於上次搭好了SSM後端框架,就想著順便把以前那個部落格網站的後臺管理系統給做了,系統的後端環境是有了,前端頁面用什麼開發呢?之前簡單的看了vue.js,所以就決定用vue.js做前端頁面,然後搜了一些vue.js配套的ui,找到了elementUI。而

vue2.0 + webpack+axios+elementUi+vue-router+vuex 搭建後臺管理系統環境部署(二)

前言 最近公司專案需要做一個小型的填報的錄入系統,根據業務的具體分析,採用了基於vue2.0 + webpack+axios+elementUi+vue-router+vuex全家桶的技術棧構建錄入系統,同時也作為學習vue全家桶技術棧的一個學習記錄。 專案初始化 第一

vue】iview-admin後臺管理系統頁面(②)

****  表示埠號 ---- 表示程序號 在①的基礎上,使用iview-admin的專案若想有如下修改 1.想修改預設埠號8080到其他未佔用埠****   1.1檢視埠****是否被佔用       windows+R 調出執行面板,輸

vue,vuex的後臺管理專案架子structure-admin,後端服務nodejs,前端vue頁面

1、vuex來實現狀態管理2、靜態頁面,未引入後端服務3、元件是用的是element-ui4、頁面佈局是上左右,左右佈局使用的彈性和佈局flex,左邊定寬,右邊計算寬度5、左右的滾動條是相互獨立的,去掉body上的滾動條6、沒有業務程式碼,僅僅是一個靜態的vuex的架子說明:之前使用左側menu的fixe

一步步帶你做vue後臺管理框架()——登入功能

系列教程《一步步帶你做vue後臺管理框架》第三課 線上體驗地址:立即體驗   認證又稱“驗證”、“鑑權”,是指通過一定的手段,完成對使用者身份的確認。身份驗證的方法有很多,基本上可分為:基於共享金鑰的身份驗證、基於生物學特徵的身份驗證和基於公開金鑰加密演算法的身份驗證。   登入鑑權功能是後臺

後臺管理頁面基本佈局方式

經典頁面佈局 簡易後臺管理頁面佈局 1 左邊選單欄固定 2 header固定高度(寬度自適應) 3 主體統計列表(寬度自適應) 程式碼如下 html <div class="main"> <header cl

Vue2.0結合iView快速搭建後臺管理網站模板(附github原始碼地址)

一、專案背景: 嘗試使用vue結合其UI框架iView快速搭建網站後臺模板(在前後端分離的大背景下,傳統的js、jquery已經不在是搭建前端的首選,尤其是mvvm模式下衍生出來的react.js、angular.js和vue.js等框架是的前端開發更加高效簡潔,效能提高的

構建一個基於Vue完整的商城後臺管理系統

###專案簡介: 該後臺管理系統是基於Vue2.0來實現的。其中包含了登入,使用者管理,商品管理,管理員許可權管理,資料統計,訂單管理,物流管理,代金券系統,支付方式配置頁面風格管理等模組。 前端技術 vue vue-cli 腳手架工具進行專案整體架構的搭建

織夢網站後臺管理網站欄目管理項不顯示問題解決辦法

織夢網站後臺管理—核心—網站欄目管理項不顯示問題解決辦法 (可能只適用於我出現的情況,須謹慎做好備份) 一、安裝輸入網址:www.xxx.com/install/index.php 注意:在安裝前檢查install資料夾 1>以.bak結尾的字尾去掉.bak; 2>

Vue + Element-ui實現後臺管理系統(4)---封裝一個ECharts元件的一點思路

# 封裝一個ECharts元件的一點思路 有關後臺管理系統之前寫過三遍部落格,看這篇之前最好先看下這三篇部落格。另外這裡只展示關鍵部分程式碼,專案程式碼放在github上: [mall-manage-system](https://github.com/yudiandemingzi/mall-manage-

Vue + Element-ui實現後臺管理系統(5)---封裝一個Form表單元件和Table表格元件

# 封裝一個Form表單元件和Table元件 有關後臺管理系統之前寫過四遍部落格,看這篇之前最好先看下這四篇部落格。另外這裡只展示關鍵部分程式碼,專案程式碼放在github上: [mall-manage-system](https://github.com/yudiandemingzi/mall-manag

Linux內存管理基本框架??

設計 內存管理 uboot page 有一個 一個 下標 size 最大 Linux內核的映射機制設計成三層,在頁面目錄和頁面表中間增設了一層“中間目錄”。在代碼中,頁面目錄稱為PGD,中間目錄稱為PMD,而頁面表稱為PT。PT中的表項稱為PTE,PTE是“Page Tab

後臺管理的前端框架

renren-fast-vue基於vue、element-ui構建開發,實現renren-fast後臺管理前端功能,提供一套更優的前端解決方案。 iview-admin基於vue、iview構建開發 前者更加簡潔,專案down下來直接改改就可以使用,表格什麼的已經建立

rabbitmq之後臺管理和使用者設定()

前言 前面介紹了erlang環境的安裝和rabbitmq環境安裝,接下來介紹rabbitmq的web管理和使用者設定。 啟用後臺管理外掛 通過後臺管理外掛我們可以動態監控mq的流量,建立使用者,佇列等。 建立目錄 mkdir /etc/rabbitmq 啟用外掛 /usr/l