cookie、session、token的理解

最近做welogger.com,想要用service worker来进行强缓存,因为访问特别慢,考虑用app shell模型来提升体验。但是出现了一个问题,API的csrf_token放在html中被缓存了的话,会跟随session的实效而失效。为了解决这个问题,貌似可以用token的方式来解决,laravel提供了passport来实现,但是自己对这些东西不是很了解,所以网上搜集了资料, 做一些学习笔记。

主要参考: https://auth0.com/blog/cookies-vs-tokens-definitive-guide/

1. 基于cookie的验证

http是无状态的,服务器不知道你是谁。当然可以每次请求都带上密码,不过这也太麻烦也不安全了。人们想到一个方法:

  1. 用户login
  2. 服务器生成回话(session),session中包含谁谁谁,什么时候登陆的信息,session有个sessionId,返回给浏览器
  3. 下一次再访问的时候,带上这个ID就行了。服务器根据session ID来判断访问者是谁。

cookie是一种特殊的存储技术,cookie按照域名存在浏览器端,当浏览器访问domainA的时候,会自动带上domainA的cookie。 很显然,上述sessionID放在cookie中最合适不过了。

用户logout的时候,清空会话,清空cookie中的sessionID

2. 基于token的验证

好了,token就是说我相信你说你是你,告诉我你是谁就行了

  1. 用户login
  2. 返回一个token(证明你是你)给浏览器
  3. 下次再访问的时候,带上这个token就行了。服务器根据token判断访问者是谁。

很显然,这个token存在哪儿都行,localstorage或者cookie。logout的时候,浏览器端删除掉token就行了。

3. 简单对比

从步骤上看,貌似二者没啥大区别,都需要获取/保存/传递一个标记,这个标记是sessionId或者token。但是在实现上还是有很大的不同。可以看到对于token而言,服务器不需要去查看你是谁,不需要保存你的会话,直接看token中的用户id就行。sessionID只是ID没有其他信息,而token则不一样,根据token的实现可以包含不同信息。

就好比去某个政府办事

  1. 服务员看你的身份证,给你一个编号,以后,进行任何操作,都出示编号后服务员去看查你是谁。
  2. 直接妹子给他看身份证

感觉还是很不一样的,实际上2看上去要简单的多。

4. token的优势

这一部分就参考的这篇文章了。

4.1 无状态,可扩展性

如前所述,服务器端不存储会话,可扩展性强,如果有多台服务器,会话信息存储地方不只一个的话,就需要某种同步机制,或者想办法知道用户和session存储地的对应关系。

4.2 跨域问题

浏览器有跨域问题,如果有好几个不同的网站的话,cookie-session的话需要在login的时候给所有的domain写上cookie,通常做法应该是有个sso endpoint,登陆成功后跳转到专门的页面,页面上用iframe之类的分别调用各个domain的写cookie endpoint。

如果用了token,只要不同的网站采用相同的验证机制,就ok了。

4.3 token里面可以存储信息

这个待会儿来看jwt(json web token)的实现。

4.4 性能

token不用查db,然后用户角色的划分,也可以通过token中的数据进行查看。

4.5 支持非浏览器环境

嗯,app之类的。

5. token的问题

5.1 token的size

sessoinId只存了id,很小。token则比较大,不过这个问题应该不大吧?

5.2 token的存储

如果存在localStorage的话,不像cookie,localStorage不支持子域名获取主域名的localStorage。如果存在cookie中,会受到4kb的限制。 这一点上,感觉localStorage的域名问题比较大,如何解决?

5.3 xss和xsrf

xss简单上说就是外部脚本闯进来了,情况比较多,比如用户的输入没有进行检查啊,用的第三方脚本出问题了的话,token就暴露在敌人眼前了。这个常见的框架应该都有保证,不要乱用应该就ok,第三方脚本也不要乱用。

xsrf是说用户在恶意网站B上面点来点去,不小心操纵了网站A的数据。比如登陆了A,A上允许post到一个url然后删除账号,结果网站B悄悄做了一个隐藏的form,用户点击的时候不经意触发了这个url,由于浏览器会带上cookie,所以直接成功了。

所以在post等重要的请求的时候,服务器需要验证这个请求是不是从网站自身上发出的。证明这个的办法是,在页面中放上一个自己才有的随机字符串(csrf_token),然后请求的时候带上这个token,服务器端进行验证。这样其他网站不能生成这个token所以也就无解了。

如果网站B上悄悄放上A的iframe,然后引诱用户去点呢? 这是另外一个问题了,这个就需要通过设置http header X-Frame-Options来禁止被用作iframe了。

如果token存在localStorage中,根据浏览器机制,token是不会被其他人知道的,所以不会出现xsrf问题,但是会出现xss的问题,xss问题可以通过http header csp来处理。

如果是存在cookie的话,可以用httpOnlyflag禁止js进行获取,所以xss可以完全避免。但是这样的话js获取不到,服务器只能通过session一样的方式,在cookie中找token,这样会遇到xsrf问题,而且cookie还有其他的很多问题。

关于安全的,我补充两个地方:

  1. MITM: 经常想如果token被人截获了怎么办?其实想想如果真有这么一个人,无论是哪种方式都是无法保证安全的。所以https是必须的,不用考虑这种半途打劫的情况。
  2. 过期问题: session也有过期时间,所以会有自动登录选项,自动续期。token也有过期时间,过期后需要重新发行token。

6. JWT

来看看 token如何实现的,貌似jwt已经成为了事实上的标准。 jwt包含三个部分

以下内容基本来自于官网 https://jwt.io/

  1. Header
  2. Payload
  3. Signature

三个部分分别处理后形成这样一个token: xxxx.yyyy.zzzz header

{
  "alg": "HS256", // 算法
  "typ": "JWT"    // token类型
}

上述信息Base64Url转换后,形成xxxx

Payload 中包含很多claim,这些claim是一些我是谁,我能干嘛的一些声明(claim)。这些claim分三种(Reserved, Public, private),种类细分暂时是TODO,后来我再看。

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

上述信息Base64Url转换后,形成yyyy

Signature 需要将上述xxxx,yyyy部分加一起,通过header中指定的加密方法,然后加上一个secret,hash过后得到。 比如上述信息的话:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

这样得到zzzz的部分

很显然,server保存的secret,所以外部是不能自己模拟产生一个合法的token。简单想想,其实就是你写了个证明,由某个机构给你改了个章。你可以自己修改其中的信息,但是章你盖不出来,所以文件没有效力,这也是为什么填文件资料填错涂改的时候,需要在涂改的部分旁边,加上一个章。 嗯。

### 回答1: CookieSession Token 在 Web 应用中都被用来跟踪用户状态。两者的主要区别在于,Cookie 是存储在用户设备上的,而 Session Token 则是存储在服务器端的。 Cookie 是由浏览器自动创建和发送给服务器的,用户可以在浏览器的设置中查看和管理它们。Cookie 中可以存储一些键值对数据,在用户的不同请求之间共享数据。Cookie 适用于存储一些简单的数据,例如用户名和密码等。 Session Token 是在用户登录时在服务器端创建,并在用户与服务器进行交互时发送。服务器端会为每个用户维护一个唯一的 Session TokenSession Token 是在服务器端存储的,用户可以在浏览器中查看,但不能编辑或删除。Session Token 适用于存储用户身份,例如权限、购物车等。 总结,Cookie主要用来存储简单的,不太敏感的数据,且存在浏览器端;而Session token用来标识用户身份,数据都是存在服务器端。 ### 回答2: cookiesessiontoken都是现在常见的认证方式,用于保证Web应用程序的安全性和隐私性。在理解三者的区别之前,需要先了解它们的基本概念含义。 1. Cookie Cookie 是服务器发送给浏览器的小型数据文件,存储在用户的计算机中。浏览器在之后的请求中会将此文件发送到服务器,以便于验证用户的身份和记录用户的行为。 Cookie 的优点在于它可以存储比 Session 更多的信息,并且可以在浏览器关闭后仍然保持数据有效。缺点是 Cookie 可以被恶意软件或黑客轻易窃取。 2. Session Session 指的是服务器创建的一个会话过程,用于在特定时间段内记录某个用户的交互状态。通过 Session,Web应用程序可以在不同的页面之间共享数据,为用户提供个性化服务。 Session 的优点在于它存储在服务器上,保障了比 Cookie 更好的安全性和隐私性。但是, Session 也会消耗服务器的资源,因此需要谨慎管理。 3. Token Token 是一种随机生成的字符串,用于验证用户的身份和权限。在 Web 应用程序中,Token 可以被用来替代 CookieSession,因为它不会存储在用户的计算机中,也不需要服务器存储用户的状态。 Token 的优点在于它们相对更安全,因为它们没有任何销售性的信息存储在用户的浏览器中。另外, Token 机制可以支持无状态应用,也就是应用程序无需保存任何会话信息,更好的支持了分布式架构。 在以上区别基础上,三者的区别主要在于存储地点(客户端或服务器端)、存储内容(数据信息)、安全性和使用场景等。 - Cookie主要存储在客户端,并可以将更多的数据存储在客户端,Session存储于服务端提供了更好的安全性,但会占用更多服务器资源,Token能够将Session信息存储于客户端,也可以保证数据安全。 - Cookie主要用于客户端与服务端的交互;Session更注重用户身份的鉴别与用户状态的维护;Token更多地用于 API 认证。 - 一般情况下Cookie的安全性最低,Session的安全性中等,Token相对而言较为安全。 - 通常情况下,Token方式的应用程序可以跨平台、跨域和分布式部署,更加灵活多变。 综上所述,Cookiesessiontoken都是Web开发中常用的验证方式,它们在存储及应用方式上均有所差别。仔细分析自身需求,选择最适合的认证方式相比盲目跟随更为优合理。 ### 回答3: CookieSessionToken都是web应用中常见的身份认证和信息存储方式,它们之间最大的不同在于其存储的位置和方式。 Cookie是由服务器在浏览器中生成的,并存储在浏览器中的文件中。当浏览器向服务器发出请求时,会自动通过Cookie中的信息向服务器证明身份。Cookie在用户登录后会保存用户名、密码和一些其他信息,以便下次登录时自动填充,从而提高用户体验。 Session是一个服务器端的解决方案,它可以在服务器端存储用户的会话信息,并且在用户进行请求时将信息传输到客户端。Session的实现依赖于Cookie,服务器通过发送一个包含Session ID的Cookie,来记录用户的会话信息,服务器则将Session信息保存在服务器端的内存或者文件系统中,以确保用户信息的安全性。 Token是一种无状态的身份认证方式,它不同于CookieSession的保存信息方式,而是保存在客户端中。当用户登录时,服务器会生成一个Token并将其返回给客户端,客户端在后续的请求中会带上这个Token,服务器会通过验证Token的合法性来判断用户的身份。 总的来说,Cookie是一种简单且易用的Web身份认证方式,Session需要服务器支持,可以更好的保证用户信息的安全性,Token则更适合Web接口/移动端API身份认证。不同的应用场景可以选择适合的认证方式,以确保用户信息和身份的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值