Cookie + Session Vs Token

310 阅读2分钟

HTTP是无状态的,即每次请求之间没有关联,为了使后端识别每一个用户,每一个从客户端发送的链接都需要有唯一标识

Cookie + Session

  • 客户端第一次请求服务器,服务端会创建Session,返回SessionId,通过Set-Cookie响应将其保存至Cookie中,客户端第二次请求,服务端解析Cookie中的SessionId,可以获取Session。

优点*:

  1. Cookie可以设置http-only属性,设置该属性后将无法通过js脚本读取,能够有效避免XSS攻击;
  2. 开箱即用,不需要在客户端实现API。

缺点

  1. Cookie会与特定的域名绑定,所以跨域访问需要配置反向代理;
  2. 容易导致CSRF/XSRF即跨站请求伪造攻击;
    • 以Java Web程序为例,session中会存储用户信息,假设用户首先登陆了一个受信任的网站A,cookie信息中将会存储会话sessionid,此时不关闭A,继续访问某钓鱼网站B,若B中存在图片<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>,点击图片之后将会跳转访问A网站,此时对A网站的session未被销毁,cookie也存在,所以A网站会认为仍然是用户操作,这样钓鱼网站B就达到了模拟用户操作的目的。
  3. 每次请求都会发送该信息,即使该请求不需要进行验证;
  4. Cookie+Session中,用户验证时一般会在Session中存储用户信息,不安全。

Token

  • 客户端请求,服务端根据用户信息创建Token,响应给客户端,客户端保存Token至Cookie/SessionLocalStorage/LocalStorage等存储空间中,客户端第二次请求,将Token放置在请求头中(规范,其实不放在请求头也可以),服务端拦截请求,获取Token并验证。

优点

  1. 可以只验证想要验证的请求;
  2. 免疫CSRF/XSRF攻击;
  3. 可以跨域共享,Token可以被发送至多个服务端,因此,域名myapp.com上的一个web应用程序可以同时向myservice1.com和myservice2.com发送授权请求;
  4. Token仅仅是个令牌,不会存储用户信息。

缺点

  1. 必须手动将Token存储到一个地方,而SessionId则会自动存储到Cookie中,常用存储位置:
    • LocalStorage
      • 缺点:即使关闭了浏览器窗口,token依然存在;
    • SessionStorage
      • 优点:关闭浏览器窗口后,token即消失;
      • 缺点:登录验证后,打开一个新的选项卡,仍然需要验证,即每个窗口存在自己的SessionStorage
    • Cookie
      • 优点:默认情况下,关闭浏览器窗口后,token即消失;
      • 缺点:每次请求,Cookie都会被发送。

注意,Cookie只是个存储空间,可以用于存储Sessionid或Token。只不过一般SessionId使用Cookie进行存储,token使用LocalStorage进行存储。