219. 單頁應用 會話管理(session、cookie、jwt)

原文連接:https://github.com/ly525/blog/issues/219前端

關鍵字:http-only, cookie,sessionid, vue-router, react-router, 安全localStorage, jwtvue

需求描述

  1. 內部管理平臺,須要用戶登陸以後才能訪問。如今將 該平臺地址(www.xxx.com/home) 直接發給新來的運營同窗
  2. 前端須要檢測該用戶是否已登陸,若是未登陸,則將其 redirect 到登陸頁面
  3. 由於該頁面爲單頁應用,路由跳轉不涉及後端的 302 跳轉,使用前端路由跳轉

實現思路

實現代碼react

// 以 vue-router 爲例
// 登陸中間驗證,頁面須要登陸而沒有登陸的狀況直接跳轉登陸
router.beforeEach((to, from, next) => {
  const hasToken = document.cookie.includes('sessionid');
  // 若是採用 jwt,則一樣 hasToken = localStorage.jwt
  const pathNeedAuth = to.matched.some(record => record.meta.requiresAuth);
  // 用戶本地沒有後端返回的 cookie 數據 && 前往的頁面須要權限
  // 
  if (pathNeedAuth && !hasToken ) {
    next({
      path: '/login',
      query: { redirect: to.fullPath },
    });
  } else if (hasToken && to.name === 'login') {
    // 已登陸 && 前往登陸頁面, 則不被容許,會重定向到首頁
    next({
      path: '/',
    });
  } else {
    next();
  }
});
  1. 應該在進入任何頁面以前,判斷:
    1. 該頁面是否須要權限才能訪問:登陸、註冊頁面不須要權限
    2. 用戶是否已經登陸:本地 cookie (或者 localStorage)包含 session 相關信息
    Cookie: csrftoken=YaHb...; sessionid=v40ld3x....
  2. 若是 A頁面須要權限本地 cookie中包含了 sessionid 字段,則容許訪問A頁面,不然跳轉到登陸頁面
    1. 備註:sessionid 該字段由用戶在登陸以後,由後端框架經過 response.setCookie 寫入前端 ,所以該字段須要和後端同窗確認
    2. 須要後端同窗在 response header 中配置cookie中該字段的 http-only屬性,容許前端讀取 cookie。不然前端經過 document.cookie 讀取到的 cookie 將不包含 sessionid 字段
    3. 這個時候,可能會存在 js 讀取cookie 致使不安全的狀況,後端同窗能夠把 cookie 中的某個字段設置爲 容許讀取,其餘 cookie 設置不容許讀取,這樣即便被第三方不安全腳本獲取,也沒法產生負面影響。
  3. 若是用戶已登陸 && 在瀏覽器中輸入了登陸頁地址,則將其重定向到首頁

更多說明

  1. 這樣作,前端就沒必要再向後端發起 API 作權限鑑定了(後端返回401,前端跳轉到 401),減小沒必要要的API 請求,特別是若是在API響應時間過長的狀況下,體驗不太友好。git

  2. 用戶修改 cookie,僞造 sessionidgithub

    1. 這樣的話,前端就無能爲力了,前端鑑權此時認爲該用戶合法。此時訪問首頁,將會調用獲取數據的API。
    2. 瀏覽器會將 用戶僞造的 sessionid 帶給後端,這時候就須要後端對 sessionid 進行較驗了。好比校驗前端帶來的 sessionid 與數據庫中的 sessionid 是否一致
    3. 用戶僞造的數據 sessionid 和 後端數據庫中 sessionid 的機率 很是很是低,能夠忽略不計,由於 sessionid 的位數通常在 32 位以上,由於裏面包含了字母和數字,也就由 32 ^ 36 種可能
    4. 結論:僞造沒有意義,即便用戶能夠看到頁面的樣子,可是看不到數據
  3. 採用 localStorage 而不是 sessionStorage 的緣由(SessionStorage 失效場景)vue-router

    緣由:sessionStorage 沒法跨 Tab 共享數據庫

    1. 用戶在新打開一個 Tab,輸入已經登陸以後的某個頁面
    2. 經過target="_blank" 來打開新頁面的時候,會致使會話失效
    3. 在當前頁面執行 Duplicate (複製 Tab),sessionStorage 失效
相關文章
相關標籤/搜索