# 前言
起因是在计网的卷子里看到了这个答案
如图,看的我一脸懵逼,颠覆了我学习了那么久web的认知。遂发到计网群讨论,结果一群人竟然认同这个答案?
其实书上关于cookie技术的解析是没错的,但是这个答案的说法完全就是瞎几把写了,如果你对着未来老板说cookie是保存在后端的,老板估计会后悔为什么录取这个傻逼。。呵呵
# 服务端中的Session
源头来说,应该先从Session说起。它的定义为会话控制,也有将其翻译为时域的。它的目的,就是在浏览器web页面跳转的时候,可以保持整个用户会话,来完成web应用的流程(登录,资源访问……)
关于WEB服务器,我使用过Tomcat和Koa2。这两者的Session默认实现,都是将Session作为一个对象,然后保存在内存中。 默认实现中,只要服务关闭,或者中途退出,原本服务器维持的Session对象们将不复存在,但是会将session集保存在一个临时文件中,如何将Session持久化是一个问题。 另外,在分布式服务器中,Session共享是一件必须的事情,为了Session共享,将Session持久化也是一个很好的方法。
持久化Session,Tomcat 默认是支持把Session持久化到文件的, 同时也可以借助组件将Session持久化到Redis,甚至SQL数据库中。
而我自己,也尝试过自己实现一个最简单Session机制,自己写用户会话管理的实现,并将用户状态信息保存到Redis中,这种做法可以减少Tomcat维护Session的负担。当然比起Tomcat已经实现的各种Session管理实现还是差很远,毕竟只是自己学习Session机制的小实验而已。
# 服务端和浏览器的会话保持
当服务端拥有了Session,但是客户端怎么与服务端相配合维持会话呢。主流就是使用Cookie技术。
Cookie技术里面:
- Cookie file 是保存在浏览器端的一个小文本文件
- http请求可以在Cookie请求头中携带Cookie信息
- http响应可以在响应头中设置Set-Cookie头来使浏览器保存Cookie
基本就是如上的定义,可见Cookie和Session之间的差别是很大了。
而Session如何使用Cookie,从生成Session对象的这个请求开始:
- 服务器收到请求,收到后生成Session对象,在响应头中写入Set-Cookie:SessionId=xxxx; 等信息。(约定了格式。)
- 浏览器收到响应,并保存cookie在用户端。
- 用户发出新的请求,请求中的Cookie请求头带上Cookie内容。
通过Cookie来在浏览器和服务端之间维持这个会话。 那么在看看前言中题目的答案,Cookie真的保存在后端数据库吗?我的理解显然不是的: 保存在后端的是Session,Session持久化不是绝对的,Cookie不仅不保存在后端,本文中情境中连数据库都没有使用 我怕是反驳我问题的人和出答案的人吧Cookie和Session搞混了,或者看着书上说Cookie技术使用了数据库技术,就似懂非懂的写上了Cookie保存在后端数据库。
如果还是不懂,那么再来一个例子 其实不是用Cookie一样可以维持Session,在不支持Cookie中的浏览器通常的做法是使用URL参数传递SessionId。而这样,连Cookie技术都不使用到了。那么你认为,Session和Cookie还是一个东西吗?
- 后端数据库保存Cookie
- 后端保存Session
- Session == Cookie? 我们先这么假设
- 使用URL参数不是用Cookie,Session依然可以维持,Cookie去哪儿呢?
- Session != Cookie?我们再这么假设
- 后端存Session+Cookie是神经病吗?
我希望通过讲述概念,和最后的这个例子,可以让能看到我博客的人了解到Session和Cookie的巨大差异,Session技术只是可以借助于Cookie技术来维持这个有状态的会话而已。
# 新的技术
对于RestAPI,有无状态是几乎没有必要的,必要的是用户的安全认证,这样新的Token技术出现了。Token机制非常契合RestAPI的安全认证需求。
而且,面对着跨域、快速等需求,Session技术和Cookie技术是很难满足的。首先,维持Session需要服务器储存和共享,并且每次都要检索Session的存在。其次,Cookie的跨域限制也非常繁琐,虽然这是为了安全,但是已经不符合许多新app应用的需求了。
关于Token,大概有以下几点优势:
- 首先,就是无状态。服务器不维护任何状态信息。
- 跨服务器,所有服务端都有统一的签发和解析算法
- 携带其他信息,比如权限,其实Cookie也可以,不过Token是加密的,Cookie其实也可以。。
- 性能,秒杀Session技术
- 跨域,如果你被Cookie跨域问题弄过,你就懂Token有多好
- 还有很多,但是我了解的不算深入,以后慢慢学习使用深入研究……
有同学比喻Session Cookie相当于令牌,其实Token技术才是真正的令牌。举个栗子
- Session Cookie只是储存(我是谁),由服务器来维护你的更多信息,“喔,服务器找到你有这个的访问权限~ ”
- Token储存的是(令牌),服务器没有你的更多信息,收到后解析发现你的更多信息,“哇,令牌上写了你真的有这个权限诶!”
这样的做法,很容易实现登录服务器与资源服务器的分离,有非常大的优势和好处。
至于如何传递Token,有很多种思路。例如,由JWT生成的Token是一段字符串,比较简单常用的是附加在请求头中,而且其实,采用cookie来传递token也是和常用的。
在非常流行的OAuth2.0中,其实也用到了Token技术,通过写这篇文章,让我对OAuth2.0授权认识有了较大的提升,我的综合设计应该不会凉了。