您好,登錄后才能下訂單哦!
開題
最近用vue來構建了一個小項目,由于項目是以iframe的形式嵌套在別的項目中的,所以對于登錄的驗證就比較的麻煩,索性后端大佬們基于現在的問題提出了解決的方案,在看到他們的解決方案之前,我先畫了一個比較標準的單系統的解決方案。
本文目錄:
一: 設想
二: 討論
三:實現
四:總結
一: 設想
簡單解釋下上圖就是:
首先前端從cookie獲取token,如果沒有token就跳轉到登錄頁面登錄,登錄驗證之后生成token存在數據庫中并返回給前端;前端將這個token保存下來,為了讓在瀏覽器新的tab頁時不需要登錄,我們前端需要將這個token保存到cookie之中。
如果用戶已經有了token,那么再驗證是否有用戶信息,如果沒有去請求用戶信息的接口,后臺讀取用戶的基本信息返回給前端,前端根據后臺返回的用戶權限生成固定的路由表用于頁面攔截。
在用戶token和權限都有的情況下,進入自己權限內的頁面并且攜帶token訪問后臺進行交互。
用戶在退出時,請求后臺接口,清除token數據。
二: 討論
由于公司的項目更加的復雜,屬于基于原來的系統開發新的系統模塊,但是這些模塊又為了以后主體功能的更新下次迭代需要保持相對的獨立性,預計以后的老系統只起一個用戶中心的功能,所以現在是基于實現單點登錄的能力去迭代更新現在的新的項目。
今天上午對于登錄的實現進行了相關討論,由于公司項目保密考慮只是單單做相關的介紹:
現有的老項目將慢慢向用戶中心轉換,而以前的新項目需要去這個用戶中心獲取登錄信息。具體的實現是:
登錄新項目b.exaplem.com通過session檢測到未登錄時(這里說下新的項目和老項目在同一個一級域名下),跳轉到a.exaplem.com?returnUrl='b.exaplem.com',在a.exaplem.com下成功登錄后生成一個ticket給到b.exaplem.com,b.exaplem.com將這個ticket存在session里面來保持登錄狀態。
因為現在基本上是先登錄a.exaplem.com然后再去登錄b.exaplem.com,所以當我們第一次進入b.exaplem.com系統時,b.exaplem.com會向a.exaplem.com系統發送請求來獲取ticket,并且生成session來維持登錄狀態。
三:實現
當時想通過引入vuex并通過cookie來保存token的狀態,但是由于現在的項目還是后端以session的形式來維持用戶的登錄狀態所以還是沒有引入vuex。
基本實現如下:
main.js增加引入的permission.js文件如下:
import Vue from 'vue' import router from './router' import { asyncRouterMap, constantRouterMap } from './router' function hasPermission(roles, route) { // if (route.meta && route.meta.role) { return roles.some(role => role === route.meta.role) } else { return true } } function filterAsyncRouter(asyncRouterMap, roles) { const accessedRouters = asyncRouterMap.filter(route => { if (hasPermission(roles, route)) { if (route.children && route.children.length) { route.children = filterAsyncRouter(route.children, roles) } return true } return false }) return accessedRouters } // 加載頁面之前 router.beforeEach((to, from, next) => { NProgress.start() // 開啟Progress if (to.path == '/ContractAduit/Error') { next() } else if (!Vue.prototype.hasRoute) { Vue.prototype.$ajax.get(Vue.prototype.$api.getModuleHost("用戶信息接口地址"), {}) .then(data => { if (data.code == 1000) { let menus = data.menu let roles = menus.map((menu, index) => { return parseInt(menu.url); }) const accessedRouters = filterAsyncRouter(asyncRouterMap, roles) router.addRoutes(accessedRouters) Vue.prototype.userInfo = { id: data.id, realname: data.realname } Vue.prototype.hasRoute = true; next({...to }) } else { router.push({ name: 'ErrorPageRouter' }); } }) .catch(err => console.log(err)) } else { next() } });
route.js文件如下:
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export const constantRouterMap = [{ path: '/404', name: 'NoFoundPagetRouter', component: require('../views/404.page'), meta: { title: '404', } }, { path: '/ContractAduit/NoAccess', name: 'NoAccessPageRouter', component: require('../views/no-access.page'), meta: { title: '無權限', } }, { path: '/ContractAduit/Error', name: 'ErrorPageRouter', component: require('../views/error.page'), meta: { title: '內部錯誤', } } ] export default new Router({ mode: 'history', routes: constantRouterMap }) export const asyncRouterMap = [{ path: '/ContractAduit/Supplier/List', name: 'SupplierListPageRouter', component: require('../views/supplier/supplier-list.page.vue'), meta: { title: '某某列表頁', role: 10001 } }, ... { path: '/', redirect: '/ContractAduit/Supplier/List', hidden: true, meta: { title: '某某列表頁', role: 10001 } }, { path: '*', redirect: '/404', hidden: true } ]
因為沒有引入vuex所以需要在VUE構造函數的原型對象上聲明變量來判斷是否已經拉取了用戶的基本信息,因為我們后端的權限是配置的頁面級權限(即不是按照角色來安排哪個前端頁面來可訪問,而是根據后臺返回的頁面代碼來判斷哪個前端頁面可訪問)。
四:總結
因為我們的項目不可能達到千篇一律的情況,選擇適合自己項目的解決方案才是最重要的,不要為了用某個技術而去用某個技術。
以上這篇vue系列之動態路由詳解【原創】就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。