深入浅出Cookie、Session、Token
深入浅出Cookie、Session、Token
Cookie、Session、Token简介
存在的意义
存在即合理,既然合理就有其意义,那么cookie、session、token存在的意义是什么呢?
HTTP 是一种没有状态的协议,就是说浏览器这一步请求并不知道上一步请求所包含的状态数据,也无法从网络连接上面知道访问者的身份。客户端使用用户名还有密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下,这难免有些琐碎而且费时费力 。
所以如何把客户端的HTTP请求关联起来就成了关键,cookie、session、token存在的意义就在于此。
Cookie
cookie指的就是浏览器里面能永久存储的一种数据,仅仅是浏览器实现的一种数据存储功能。
cookie由服务器生成,发送给浏览器,浏览器把cookie以kv(key-value)形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。
cookie的缺陷:客户端就能修改数据,不能存放重要数据,当cookie中的数据字段过多就会影响传输效率。
Session
session 从字面上讲,就是会话,目的是为无状态的HTTP提供的持久机制。服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识”,服务器就知道这个请求来自于谁了。
session是放在服务器端的,其运作是通过session_id进行的,session_id在第一次被访问的时候就被存放在cookie中,当你下次访问的时候,cookie带着session_id,服务器就知道你访问过哪里,并将session_id和服务器端的session data关联起来,进行数据保存和修改。
session 的缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。
Cookie与Session的区别
1、cookie数据存放在客户端上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、一般而言,登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。
Token
token从字面上讲,就是令牌。用于验证表明身份的数据或口令数据。
token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接token请求服务器)。
token 是通过 HMACSHA256 算法生成,header 和 payload 是 Base64URL 编码,这不是加密。里面不能携带一些敏感数据,比如密码,绝对不能存储在 payload 中。如果你必须存储敏感信息在 payload 中,你可以使用 JWE(JSON Web Encryption)。WE 允许你去加密 JWT 的内容,让其除了服务器以外的任何人都不可读。JOSE 为 JWE 提供了一个很好的框架,并为许多流行框架(包括 NodeJS 和 Java)提供了 SDK。
使用token的目的:1.token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。2.可以防御CSRF攻击。
Session与Token的区别
session 和 token其实并无本质区别,都是为无状态的HTTP提供的持久机制。但作为身份认证 token安全性比session好,因为每个请求都有签名还能防止监听以及重放攻击,而session就必须靠链路层来保障通讯安全了。
验证流程
HTTP Basic Auth验证流程
简而言之,HTTP Basic Auth就是每次请求API时都需要提供用户的username和password的认证方式。
但由于有把用户名密码暴露给第三方客户端的风险,在生产环境下被使用的越来越少。
因此,在开发对外开放的RESTful API时,应该尽量避免采用HTTP Basic Auth。
Cookie机制的验证流程
cookie 验证是有状态的,意味着验证记录或者会话需要一直在服务端和客户端保持。
cookie的内容主要包括name(名字)、value(值)、maxAge(失效时间)、path(路径),domain(域)和secure。
- 用户登录,输入账号密码
- 服务器验证用户账号密码正确,创建一个 session 存储在数据库(或者 redis缓存)
- 将 session ID 放进 cookie 中,被存储在用户浏览器中。
- 再次发起请求,服务器直接通过 session ID 对用户进行验证
- 一旦用户登出,则 session 在客户端和服务器端都被销毁
Token机制的验证流程
token 验证是无状态的,服务器不记录哪些用户登录了或者哪些 JWT 被发布了,而是每个请求都带上了服务器需要验证的 token,token 放在了 Authorization header 中,形式是 Bearer { JWT },但是也可以在 post body 里发送,甚至作为 query parameter。
- 用户输入登录信息
- 服务器判断登录信息正确,返回一个 token
- token 存储在客户端,大多数通常在 local storage,但是也可以存储在 session storage 或者 cookie中。
- 接着发起请求的时候将 token 放进 Authorization header,或者同样可以通过上面的方式。
- 服务器端解码 JWT 然后验证 token,如果 token 有效,则处理该请求。
- 一旦用户登出,token 在客户端被销毁,不需要经过服务器端。
JWT是一种安全标准。基本思路就是用户提供用户名和密码给认证服务器,服务器验证用户提交信息信息的合法性;如果验证成功,会产生并返回一个Token(令牌),用户可以使用这个token访问服务器上受保护的资源。
Token机制相对于Cookie机制的好处
- 支持跨域访问:Cookie是不允许垮域访问,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输。
- 无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token
自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息。 - 更适用CDN:可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可。
- 去耦:不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可。
- 更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
- CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。
- 性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析要费时得多。
- 不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理。
- 基于标准化:你的API可以采用标准化的 JSON Web Token (JWT)。这个标准已经存在多个后端库(.NET, Ruby,
Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft)。
OAuth&OAuth2.0结合Token(Access_Token)验证流程
OAuth&OAuth2.0是开放的授权标准协议,允许用户让第三方应用访问该用户在某一web服务上存储的私密的资源,而无需将用户名和密码提供给第三方应用。
OAuth&OAuth2.0结合Token(Access_Token)验证流程的相关知识,个人推荐我写过的两篇博客,理实交融,写的很详细。
深入理解基于OAuth2.0&第三方登录之GitHub实践
第三方登陆实践之基于OAuth的FACEBOOK Web Login(最新版)
部分参考资料
Cookie,Session和Token机制和区别
cookie,token验证的区别
Cookie/Session机制详解
总结
本文主要是结合自己所学知识,和众多参考资料,探讨了Cookie、Session、Token存在的意义以及相关的知识。
希望能对大家有所帮助~ 有问题欢迎留言交流,不足之处还请多多指正。