日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
前端真的能做到徹底權(quán)限控制嗎?

有一天突然想到一個(gè)問題,web端的權(quán)限控制:

創(chuàng)新互聯(lián)專注于企業(yè)網(wǎng)絡(luò)營(yíng)銷推廣、網(wǎng)站重做改版、潢川網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5開發(fā)、成都商城網(wǎng)站開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為潢川等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

1.真的能控制權(quán)限嗎?

2.僅僅靠前端,能不能做到真正的權(quán)限控制?

3.如果需要后臺(tái)配合,應(yīng)該如何配合?

可能這是一個(gè)老生常談的問題,但還是想整理下,有誤的地方望大家指出。

何為權(quán)限控制

權(quán)限控制大致分為兩個(gè)維度:

  • 垂直維度: 控制用戶可以訪問哪些url的權(quán)限
  • 水平維度: 控制用戶訪問特定url,獲取哪些數(shù)據(jù)的權(quán)限(e.g. 普通用戶、管理員、超級(jí)管理員訪問同一url,獲取的數(shù)據(jù)是不同的) 

Web權(quán)限控制方案List

  • 前后端不分離:以Java為例,后端通過jsp、freemark、thmeleaf等模板來渲染相應(yīng)權(quán)限的數(shù)據(jù),渲染完呈現(xiàn)在瀏覽器端 
  • 前后端分離:
    • SPA單頁(yè)面應(yīng)用,路由由前端控制,前端通過js控制hash路由的權(quán)限
    • SSR服務(wù)端渲染,Node中間層做代理路由,判斷權(quán)限渲染特定的路由至瀏覽器端 

SPA前端權(quán)限控制方案

SPA: 單頁(yè)Web應(yīng)用(single page web application)將所有web活動(dòng)局限于一個(gè)html頁(yè)面中,利用js通過hash或者瀏覽器history api來實(shí)現(xiàn)無(wú)刷新路由跳轉(zhuǎn),前后端通過ajax數(shù)據(jù)通信,避免了瀏覽器的刷新重新加載,為用戶提供流程的操作體驗(yàn)。這意味著前端接管了路由層,需要通過調(diào)用前端自身的MVC模塊,來渲染不同的頁(yè)面。

Base on:

  • Vue 前端MVVM框架
  • Vuex 狀態(tài)管理機(jī)
  • Vue-router 路由
  • Axios HTTP請(qǐng)求庫(kù) 

1.登陸事件Login

 
 
 
 
  1. // 1.觸發(fā)登陸事件 
  2.  
  3. dispatch('login')  
  4.  
  5. // actions 
  6.  
  7. commit(types.LOGIN_SUCCESS, res.data.data) 
  8.  
  9. ...  

2.獲取Token,經(jīng)Base64編碼后存至sessionStorage

 
 
 
 
  1. // mutations 
  2.  
  3. const mutations = { 
  4.  
  5.     [types.LOGIN_SUCCESS] (state, data) { 
  6.  
  7.         state.authlock = false 
  8.  
  9.     // 2.登陸成功回調(diào)拿到token,經(jīng)Base64 編碼后存入本地sessionStorage 
  10.  
  11.         let token = Base64.encode(data + ':HIKDATAE') 
  12.  
  13.         sessionStorage.setItem('userToken', token) 
  14.  
  15.     // 路由跳轉(zhuǎn)至目標(biāo)頁(yè)面 
  16.  
  17.         router.push({name: 'xxx'}) 
  18.  
  19.     }, 
  20.  
  21.     [types.LOGOUT_SUCCESS] (state) { 
  22.  
  23.         state.authlock = true 
  24.  
  25.     // 登出成功回調(diào),移除本地token 
  26.  
  27.         sessionStorage.removeItem('userToken') 
  28.  
  29.         router.push({name: 'Login'}) 
  30.  
  31.     } 
  32.  
  33. }  

3.所有HTTP Header Authorization 加上編碼后的token(前后端可約定規(guī)則)

 
 
 
 
  1. // Axios 請(qǐng)求鉤子(request) 
  2.  
  3. axios.interceptors.request.use(req => { 
  4.  
  5.     let token = sessionStorage.getItem('user')      
  6.  
  7.     if (token) {          
  8.  
  9.         // 3.token 存在,則在之后所有請(qǐng)求的http請(qǐng)求頭 Authorization 帶上base64編碼后的token,后臺(tái)拿到token后進(jìn)行驗(yàn)證權(quán)限          
  10.  
  11.         req.headers.Authorization = `Basic ${token}`      
  12.  
  13.     } 
  14.  
  15.     req.data = qs.stringify(req.data)      
  16.  
  17.     return req  
  18.  
  19. }, error => { 
  20.  
  21.     return Promise.reject(error)  
  22.  
  23. })  

瀏覽器http header

4.請(qǐng)求攔截:后臺(tái)拿到token后對(duì)每個(gè)請(qǐng)求進(jìn)行校驗(yàn),若校驗(yàn)失敗返回401,前端response鉤子里統(tǒng)一catch error 跳轉(zhuǎn)至登陸頁(yè)面 

 
 
 
 
  1. // Axios 請(qǐng)求鉤子(response) 
  2.  
  3. axios.interceptors.response.use(res => { 
  4.  
  5.     return res 
  6.  
  7. }, error => { 
  8.  
  9.     if (error.response) { 
  10.  
  11.         switch (error.response.status) { 
  12.  
  13.         // 4.所有接口response校驗(yàn)鉤子,若token檢驗(yàn)失敗,后臺(tái)返回 401 error code, 清除token信息并跳轉(zhuǎn)到登錄頁(yè)面 
  14.  
  15.             case 401: 
  16.  
  17.                 store.commit(types.LOGOUT) 
  18.  
  19.                 router.replace({ 
  20.  
  21.                     path: '/login' 
  22.  
  23.         }) 
  24.  
  25.     } 
  26.  
  27.     } 
  28.  
  29.     return Promise.reject(error) 
  30.  
  31. })  

5.路由跳轉(zhuǎn)攔截:任意路由跳轉(zhuǎn)時(shí),在路由beforeEach鉤子里校驗(yàn)本地是否存在token,若沒有,則跳轉(zhuǎn)至登陸頁(yè)面

 
 
 
 
  1. // 路由鉤子(每個(gè)路由跳轉(zhuǎn)前調(diào)起beforeEach鉤子) 
  2.  
  3. router.beforeEach((to, from, next) => { 
  4.  
  5.   if (to.path === '/login') { 
  6.  
  7.     sessionStorage.removeItem('userToken') 
  8.  
  9.   } 
  10.  
  11.   let user = sessionStorage.getItem('userToken') 
  12.  
  13.   if (!user && to.path !== '/login') { 
  14.  
  15.     // 若本地token不存在,則任意路由跳轉(zhuǎn)的時(shí)候,重定向至login 登陸頁(yè)面 
  16.  
  17.     next({ path: '/login' }) 
  18.  
  19.   } else { 
  20.  
  21.     next() 
  22.  
  23.   } 
  24.  
  25. })  

6.登出Logout:清楚本地sessionStorage的token信息 

 
 
 
 
  1. // mutations 
  2.  
  3. const mutations = { 
  4.  
  5.     ... 
  6.  
  7.     [types.LOGOUT_SUCCESS] (state) { 
  8.  
  9.         state.authlock = true 
  10.  
  11.     // 登出成功回調(diào),移除本地token 
  12.  
  13.         sessionStorage.removeItem('userToken') 
  14.  
  15.     router.push({name: 'Login'}) 
  16.  
  17.     } 
  18.  
  19. }  

流程示意圖如下:

寫完才覺得,什么才是真正的安全權(quán)限?任重而道遠(yuǎn)。。。


網(wǎng)頁(yè)題目:前端真的能做到徹底權(quán)限控制嗎?
當(dāng)前鏈接:http://www.dlmjj.cn/article/dpgpdcj.html