219. 單頁應用 會話管理(session、cookie、jwt)
原文連結:https://github.com/ly525/blog...
關鍵字:http-only
,cookie
,sessionid
,vue-router
,react-router
,安全
,localStorage
,jwt
需求描述
- 內部管理平臺,需要使用者登入之後才能訪問。現在將 該平臺地址(www.xxx.com/home) 直接發給新來的運營同學
- 前端需要檢測該使用者是否已登入,如果未登入,則將其 redirect 到登入頁面
- 因為該頁面為單頁應用,路由跳轉不涉及後端的 302 跳轉,使用前端路由跳轉
實現思路
實現程式碼
// 以 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(); } });
-
應該在進入任何頁面之前,判斷:
- 該頁面是否需要許可權才能訪問:登入、註冊頁面不需要許可權
-
使用者是否已經登入:本地 cookie (或者 localStorage)包含 session 相關資訊
Cookie: csrftoken=YaHb...; sessionid=v40ld3x....
-
如果
A頁面需要許可權
且本地 cookie中包含了 sessionid 欄位
,則允許訪問A頁面,否則跳轉到登入頁面response.setCookie
-
如果
使用者已登入
&& 在瀏覽器中輸入了登入頁
地址,則將其重定向到首頁
更多說明
- 這樣做,前端就不必再向後端發起 API 做許可權鑑定了(後端返回401,前端跳轉到 401),減少不必要的API 請求,特別是如果在API響應時間過長的情況下,體驗不太友好。
-
使用者修改 cookie,偽造 sessionid
使用者偽造的 sessionid
-
採用 localStorage 而不是 sessionStorage 的原因(SessionStorage 失效場景)
原因:sessionStorage 無法跨 Tab 共享
target="_blank" Duplicate