今天看了下我们项目的代码,其中在用户登录后,如何保存cookie的,做了下调研,同时我们也用了localStorage技术,避免频繁与服务器的交互,保存浏览器本地的数据。

以下是摘自网上的文章,是一些概念,具体的实现,可以看我最下面的代码。

一.Cookies 与 Session的区别及使用
HTTP是一种无状态的协议,不知道链接是谁发起的,所以需要浏览器把登录信息存起来,Session和Cookie就是为解决这个问题而提出来的两个机制。

1.Cookie是服务器在本地机器上存储的小段文本,并随每一个请求发送至同一服务器,是在客户端保持状态的方案。有时也用Cookies,指某些网站为了辨别用户身份,进行session跟踪而存储在本地终端上的数据,通常经过加密。一般应用最典型的案列就是判断注册用户是否已经登过该网站。Cookie的主要内容包括:名字,值,过期时间,路径和域。

过期时间如不设,则浏览器关掉就消失,存储在内存当中;否则就按设置的时间来存储在硬盘上的,过期后自动清除。
路径和域就是对应的域名,a网站的cookie自然不能给b用。
2.Session存储在服务端,每建立一个连接就会生成一个Session ID,并将其通过响应发送到浏览器。浏览器把Session ID存在Cookie中,浏览器第二次发送请求会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到对应的存放用户数据的类HashTable结构。

当用户在应用程序的 Web页间跳转时,存储在 Session 对象中的变量不会丢失而是在整个用户会话中一直存在下去。
一般这个值会有个时间限制,超时后毁掉这个值,默认30分钟。
Cookie与Session的区别

存储数据量方面:Session 能够存储任意的 java 对象,SCookie 只能存储 String 类型的对象
Cookie 在客户端,Session在服务端。因Cookie在客户端所以可以编辑伪造,不是十分安全。
Session过多时会消耗服务器资源,大型网站会有专门Session服务器,Cookie存在客户端没问题。
域的支持范围不一样,比方说a.com的Cookie在a.com下都能用,而www.a.com的Session在api.a.com下都不能用,解决这个问题的办法是JSONP或者跨域资源共享。
3.LocalStorage 和SessionStorage:两者都是仅在客户端(即浏览器)中保存,不参与和服务器的通信;

localStorage - 没有时间限制的数据存储

sessionStorage - 针对一个 session 的数据存储,当用户关闭浏览器窗口后,数据会被删除。

Cookie 与SessionStorage 、LocalStorage 的区别(共同点:都是保存在浏览器端,且同源的。)

Cookie数据始终在同源的http请求中携带(即使不需要),即Cookie在浏览器和服务器间来回传递;Cookie数据还有路径(path)的概念,可以限制Cookie只属于某个路径下。存储大小限制也不同,Cookie数据不能超过4k,同时因为每次http请求都会携带Cookie,所以Cookie只适合保存很小的数据,如会话标识。而SessionStorage和LocalStorage不会自动把数据发给服务器,仅在本地保存。SessionStorage和LocalStorage 虽然也有存储大小的限制,但比Cookie大得多,可以达到5M或更大。
数据有效期不同,SessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。
二.Web Storage 事件通知机制
Web Storage API内建了一套事件通知机制,当存储区域的内容发生改变(包括增加、修改、删除数据)时,就会自动触发 storage 事件,并把它发送给所有感兴趣的监听者。因此,如果需要跟踪存储区域的改变,就需要在关心存储区域内容的页面监听 storage 事件。

所有支持 localStorage 的浏览器都支持 storage 事件,包括 IE8。

但IE 8不支持 W3C 标准的 addEventListener。因此,为了监听 storage 事件,还需要检测浏览器支持哪种事件机制:

if (window.addEventListener) {
    window.addEventListener("storage", handleStorage, false);
} else {
    window.attachEvent("onstorage", handleStorage);
}
handleStorage 回调函数接受一个 StorageEvent 参数,在IE中,StorageEvent对象保存在 window.event 里面。

function handleStorage(e) {
  if (!e) {
    e = window.event;
  }
}
此时,变量 e 就是一个 StorageEvent 对象,这个对象有很多有用的属性。这些属性及含义请移步参考文章:https://blog.csdn.net/ixygj197875/article/details/80114096
本项目具体的实现如下:

if (response.data.code === '10000') {
      const { data } = response.data;
        ---------
        //部分用户信息实现Cookie保存
        axios.defaults.headers.common['Authorization'] = 'bearer ' + data.access_token;
        // data.access_token && Cookie.set('authData', data.access_token);
        data.access_token && localStorage.setItem('authData', data.access_token);
        data.enterpriseId && Cookie.set('enterpriseId', data.enterpriseId);
        data.enterpriseCode && Cookie.set('enterpriseCode', data.enterpriseCode);
        data.enterpriseName && Cookie.set('enterpriseName', data.enterpriseName);
        data.enterpriseLogo && Cookie.set('enterpriseLogo', data.enterpriseLogo);
        data.userId && Cookie.set('userId', data.userId);
        data.username && Cookie.set('username', data.username);
        data.userFullName && Cookie.set('userFullName', data.userFullName);
        data.userLogo && Cookie.set('userLogo', data.userLogo);
        data.expires_in && Cookie.set('expireData', moment().add(data.expires_in, 'seconds'));
        data.refresh_token && Cookie.set('refresh_token', data.refresh_token);
        Cookie.set('theme', 'light');
        Cookie.set('isNotLogin', 0);
        data.auto && Cookie.set('auto', data.auto);

        //rightMenu、rightHandler实现本地localStorage保存
        data.rightMenu && localStorage.setItem('rightMenu', data.rightMenu); // 权限信息存储
        data.right && localStorage.setItem('rightHandler', data.right); // 权限信息存储
        yield put({ // 存入reducer
          type: commonAction.changeCommonStore,
          payload: {
            username: data.username,
            userFullName: data.userFullName,
            userLogo: data.userLogo || '',
          },
        });
        if (data.auto === '1') {//导入用户/生成用户 需走完善密码步骤
          yield put({
            type: loginAction.CHANGE_LOGIN_STORE_SAGA,
            params: {
              importUser: true,
              pageTab: 'joinIn',
              joinStep: 3,
            },
          });
        } else if (data.auto === '0') {//正常用户,直接登录
          yield put({ type: loginAction.USER_NAME_LOGIN_SUCCESS, data });
        }
      } else {
        const newParams = { ...params };
        data.userEnterpriseStatus && (newParams.userEnterpriseStatus = data.userEnterpriseStatus);
        yield put({ type: loginAction.CHANGE_LOGIN_STORE_SAGA, params: newParams });
      }
    } else {
      yield put({ type: loginAction.USER_NAME_LOGIN_FAIL, data: response.data });
      message.error(response.data.message);
    }
  } catch (e) {
    console.log(e);
  }

通过浏览器也可以看到我们的保存数据cookie和storage。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐