219. 单页应用 会话管理(session、cookie、jwt)

原文连接: https://github.com/ly525/blog...

关键字:http-only, cookie,sessionid, vue-router, react-router, 安全localStorage, jwt前端

需求描述

  1. 内部管理平台,须要用户登陆以后才能访问。如今将 该平台地址(www.xxx.com/home) 直接发给新来的运营同窗
  2. 前端须要检测该用户是否已登陆,若是未登陆,则将其 redirect 到登陆页面
  3. 由于该页面为单页应用,路由跳转不涉及后端的 302 跳转,使用前端路由跳转

实现思路

实现代码vue

// 以 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. 应该在进入任何页面以前,判断:react

    1. 该页面是否须要权限才能访问:登陆、注册页面不须要权限
    2. 用户是否已经登陆:本地 cookie (或者 localStorage)包含 session 相关信息git

      Cookie: csrftoken=YaHb...; sessionid=v40ld3x....
  2. 若是 A页面须要权限本地 cookie中包含了 sessionid 字段,则容许访问A页面,不然跳转到登陆页面github

    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响应时间过长的状况下,体验不太友好。
  2. 用户修改 cookie,伪造 sessionidvue-router

    1. 这样的话,前端就无能为力了,前端鉴权此时认为该用户合法。此时访问首页,将会调用获取数据的API。
    2. 浏览器会将 用户伪造的 sessionid 带给后端,这时候就须要后端对 sessionid 进行较验了。好比校验前端带来的 sessionid 与数据库中的 sessionid 是否一致
    3. 用户伪造的数据 sessionid 和 后端数据库中 sessionid 的几率 很是很是低,能够忽略不计,由于 sessionid 的位数通常在 32 位以上,由于里面包含了字母和数字,也就由 32 ^ 36 种可能
    4. 结论:伪造没有意义,即便用户能够看到页面的样子,可是看不到数据
  3. 采用 localStorage 而不是 sessionStorage 的缘由(SessionStorage 失效场景)数据库

    缘由:sessionStorage 没法跨 Tab 共享
    1. 用户在新打开一个 Tab,输入已经登陆以后的某个页面
    2. 经过target="_blank" 来打开新页面的时候,会致使会话失效
    3. 在当前页面执行 Duplicate (复制 Tab),sessionStorage 失效
相关文章
相关标签/搜索